Skip to content

Commit

Permalink
Prevent crashing for negative bit shifts
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanvelzen committed Jun 20, 2022
1 parent 3926ff8 commit f243189
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 2 deletions.
4 changes: 2 additions & 2 deletions phpstan-baseline.neon
Expand Up @@ -245,12 +245,12 @@ parameters:
path: src/Reflection/InitializerExprTypeResolver.php

-
message: "#^Binary operation \"\\<\\<\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\|string\\|null results in an error\\.$#"
message: "#^Binary operation \"\\<\\<\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\<0, max\\>\\|string\\|null results in an error\\.$#"
count: 1
path: src/Reflection/InitializerExprTypeResolver.php

-
message: "#^Binary operation \"\\>\\>\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\|string\\|null results in an error\\.$#"
message: "#^Binary operation \"\\>\\>\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\<0, max\\>\\|string\\|null results in an error\\.$#"
count: 1
path: src/Reflection/InitializerExprTypeResolver.php

Expand Down
9 changes: 9 additions & 0 deletions src/Reflection/InitializerExprTypeResolver.php
Expand Up @@ -58,6 +58,7 @@
use PHPStan\Type\TypeUtils;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Throwable;
use function array_keys;
use function count;
use function dirname;
Expand Down Expand Up @@ -1097,6 +1098,10 @@ public function getShiftLeftType(Expr $left, Expr $right, callable $getTypeCallb
throw new ShouldNotHappenException();
}

if ($rightNumberType->getValue() < 0) {
return new ErrorType();
}

$resultType = $this->getTypeFromValue($leftNumberType->getValue() << $rightNumberType->getValue());
if ($generalize) {
$resultType = $resultType->generalize(GeneralizePrecision::lessSpecific());
Expand Down Expand Up @@ -1146,6 +1151,10 @@ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCall
throw new ShouldNotHappenException();
}

if ($rightNumberType->getValue() < 0) {
return new ErrorType();
}

$resultType = $this->getTypeFromValue($leftNumberType->getValue() >> $rightNumberType->getValue());
if ($generalize) {
$resultType = $resultType->generalize(GeneralizePrecision::lessSpecific());
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -916,6 +916,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7153.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/in-array-non-empty.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4117.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7490.php');
}

/**
Expand Down
10 changes: 10 additions & 0 deletions tests/PHPStan/Analyser/data/bug-7490.php
@@ -0,0 +1,10 @@
<?php declare(strict_types=1);

namespace Bug7490;

use function PHPStan\Testing\assertType;

function () {
assertType('*ERROR*', 1 << -1);
assertType('*ERROR*', 1 >> -1);
};

0 comments on commit f243189

Please sign in to comment.