mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Exit early when encountering complicated conditionals
This commit is contained in:
parent
370874d9b6
commit
fb83da94bd
6
src/Psalm/Exception/ComplicatedExpressionException.php
Normal file
6
src/Psalm/Exception/ComplicatedExpressionException.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Exception;
|
||||
|
||||
class ComplicatedExpressionException extends \Exception
|
||||
{
|
||||
}
|
@ -3,6 +3,7 @@ namespace Psalm\Type;
|
||||
|
||||
use PhpParser;
|
||||
use Psalm\Codebase;
|
||||
use Psalm\Exception\ComplicatedExpressionException;
|
||||
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
|
||||
use Psalm\Internal\Clause;
|
||||
use Psalm\CodeLocation;
|
||||
@ -12,6 +13,9 @@ use Psalm\Type\Algebra;
|
||||
|
||||
class Algebra
|
||||
{
|
||||
/** @var int */
|
||||
private static $clause_count = 0;
|
||||
|
||||
/**
|
||||
* @param array<string, array<int, array<int, string>>> $all_types
|
||||
*
|
||||
@ -342,8 +346,8 @@ class Algebra
|
||||
*/
|
||||
private static function groupImpossibilities(array $clauses)
|
||||
{
|
||||
if (count($clauses) > 5000) {
|
||||
return [];
|
||||
if (static::$clause_count > 500) {
|
||||
throw new ComplicatedExpressionException();
|
||||
}
|
||||
|
||||
$clause = array_shift($clauses);
|
||||
@ -353,8 +357,8 @@ class Algebra
|
||||
if ($clauses) {
|
||||
$grouped_clauses = self::groupImpossibilities($clauses);
|
||||
|
||||
if (count($grouped_clauses) > 5000) {
|
||||
return [];
|
||||
if (static::$clause_count > 500) {
|
||||
throw new ComplicatedExpressionException();
|
||||
}
|
||||
|
||||
foreach ($grouped_clauses as $grouped_clause) {
|
||||
@ -375,6 +379,8 @@ class Algebra
|
||||
$new_clause = new Clause($new_clause_possibilities, false, true, true);
|
||||
|
||||
$new_clauses[] = $new_clause;
|
||||
|
||||
self::$clause_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -388,6 +394,8 @@ class Algebra
|
||||
$new_clause = new Clause([$var => [$impossible_type]]);
|
||||
|
||||
$new_clauses[] = $new_clause;
|
||||
|
||||
self::$clause_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -500,12 +508,22 @@ class Algebra
|
||||
*/
|
||||
public static function negateFormula(array $clauses)
|
||||
{
|
||||
if (count($clauses) > 1000) {
|
||||
return [];
|
||||
}
|
||||
|
||||
self::$clause_count = 0;
|
||||
|
||||
foreach ($clauses as $clause) {
|
||||
self::calculateNegation($clause);
|
||||
}
|
||||
|
||||
$negated = self::simplifyCNF(self::groupImpossibilities($clauses));
|
||||
return $negated;
|
||||
try {
|
||||
$negated = self::simplifyCNF(self::groupImpossibilities($clauses));
|
||||
return $negated;
|
||||
} catch (ComplicatedExpressionException $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -826,6 +826,64 @@ class TypeAlgebraTest extends TestCase
|
||||
$array = [$x => 2];
|
||||
echo $array["_a"];',
|
||||
],
|
||||
'noMemoryIssueWithLongConditional' => [
|
||||
'<?php
|
||||
|
||||
function foo(int $c) : string {
|
||||
if (!($c >= 0x5be && $c <= 0x10b7f)) {
|
||||
return "LTR";
|
||||
}
|
||||
|
||||
if ($c <= 0x85e) {
|
||||
if ($c === 0x5be ||
|
||||
$c === 0x5c0 ||
|
||||
$c === 0x5c3 ||
|
||||
$c === 0x5c6 ||
|
||||
($c >= 0x5d0 && $c <= 0x5ea) ||
|
||||
($c >= 0x5f0 && $c <= 0x5f4) ||
|
||||
$c === 0x608 ||
|
||||
($c >= 0x712 && $c <= 0x72f) ||
|
||||
($c >= 0x74d && $c <= 0x7a5) ||
|
||||
$c === 0x7b1 ||
|
||||
($c >= 0x7c0 && $c <= 0x7ea) ||
|
||||
($c >= 0x7f4 && $c <= 0x7f5) ||
|
||||
$c === 0x7fa ||
|
||||
($c >= 0x800 && $c <= 0x815) ||
|
||||
$c === 0x81a ||
|
||||
$c === 0x824 ||
|
||||
$c === 0x828 ||
|
||||
($c >= 0x830 && $c <= 0x83e) ||
|
||||
($c >= 0x840 && $c <= 0x858) ||
|
||||
$c === 0x85e
|
||||
) {
|
||||
return "RTL";
|
||||
}
|
||||
} elseif ($c === 0x200f) {
|
||||
return "RTL";
|
||||
} elseif ($c >= 0xfb1d) {
|
||||
if ($c === 0xfb1d ||
|
||||
($c >= 0xfb1f && $c <= 0xfb28) ||
|
||||
($c >= 0xfb2a && $c <= 0xfb36) ||
|
||||
($c >= 0xfb38 && $c <= 0xfb3c) ||
|
||||
$c === 0xfb3e ||
|
||||
($c >= 0x10a10 && $c <= 0x10a13) ||
|
||||
($c >= 0x10a15 && $c <= 0x10a17) ||
|
||||
($c >= 0x10a19 && $c <= 0x10a33) ||
|
||||
($c >= 0x10a40 && $c <= 0x10a47) ||
|
||||
($c >= 0x10a50 && $c <= 0x10a58) ||
|
||||
($c >= 0x10a60 && $c <= 0x10a7f) ||
|
||||
($c >= 0x10b00 && $c <= 0x10b35) ||
|
||||
($c >= 0x10b40 && $c <= 0x10b55) ||
|
||||
($c >= 0x10b58 && $c <= 0x10b72) ||
|
||||
($c >= 0x10b78 && $c <= 0x10b7f)
|
||||
) {
|
||||
return "RTL";
|
||||
}
|
||||
}
|
||||
|
||||
return "LTR";
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user