From fb83da94bd7833ae9b25f7062d3cbe522c2fd9d7 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Tue, 8 Jan 2019 09:02:41 -0500 Subject: [PATCH] Exit early when encountering complicated conditionals --- .../ComplicatedExpressionException.php | 6 ++ src/Psalm/Type/Algebra.php | 30 ++++++++-- tests/TypeAlgebraTest.php | 58 +++++++++++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/Psalm/Exception/ComplicatedExpressionException.php diff --git a/src/Psalm/Exception/ComplicatedExpressionException.php b/src/Psalm/Exception/ComplicatedExpressionException.php new file mode 100644 index 000000000..deaf37404 --- /dev/null +++ b/src/Psalm/Exception/ComplicatedExpressionException.php @@ -0,0 +1,6 @@ +>> $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 []; + } } /** diff --git a/tests/TypeAlgebraTest.php b/tests/TypeAlgebraTest.php index cc0598f5f..6745785b5 100644 --- a/tests/TypeAlgebraTest.php +++ b/tests/TypeAlgebraTest.php @@ -826,6 +826,64 @@ class TypeAlgebraTest extends TestCase $array = [$x => 2]; echo $array["_a"];', ], + 'noMemoryIssueWithLongConditional' => [ + '= 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"; + }' + ], ]; }