|
238 | 238 | class NodeScopeResolver |
239 | 239 | { |
240 | 240 |
|
| 241 | + private const BOOLEAN_EXPRESSION_MAX_PROCESS_DEPTH = 16; |
| 242 | + |
241 | 243 | private const LOOP_SCOPE_ITERATIONS = 3; |
242 | 244 | private const GENERALIZE_AFTER_ITERATION = 1; |
243 | 245 |
|
@@ -3659,6 +3661,21 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto |
3659 | 3661 | ); |
3660 | 3662 | return $result; |
3661 | 3663 | } elseif ($expr instanceof BooleanOr || $expr instanceof BinaryOp\LogicalOr) { |
| 3664 | + if ($this->getBooleanExpressionDepth($expr->left) > self::BOOLEAN_EXPRESSION_MAX_PROCESS_DEPTH) { |
| 3665 | + $leftResult = $this->processExprNode($stmt, $expr->left, $scope, $storage, $nodeCallback, $context->enterDeep()); |
| 3666 | + $rightResult = $this->processExprNode($stmt, $expr->right, $scope, $storage, $nodeCallback, $context); |
| 3667 | + |
| 3668 | + return new ExpressionResult( |
| 3669 | + $scope, |
| 3670 | + $leftResult->hasYield() || $rightResult->hasYield(), |
| 3671 | + $leftResult->isAlwaysTerminating(), |
| 3672 | + array_merge($leftResult->getThrowPoints(), $rightResult->getThrowPoints()), |
| 3673 | + array_merge($leftResult->getImpurePoints(), $rightResult->getImpurePoints()), |
| 3674 | + static fn (): MutatingScope => $scope, |
| 3675 | + static fn (): MutatingScope => $scope, |
| 3676 | + ); |
| 3677 | + } |
| 3678 | + |
3662 | 3679 | $leftResult = $this->processExprNode($stmt, $expr->left, $scope, $storage, $nodeCallback, $context->enterDeep()); |
3663 | 3680 | $rightResult = $this->processExprNode($stmt, $expr->right, $leftResult->getFalseyScope(), $storage, $nodeCallback, $context); |
3664 | 3681 | $rightExprType = $rightResult->getScope()->getType($expr->right); |
@@ -7848,4 +7865,18 @@ private function inferForLoopExpressions(For_ $stmt, Expr $lastCondExpr, Mutatin |
7848 | 7865 | return $bodyScope; |
7849 | 7866 | } |
7850 | 7867 |
|
| 7868 | + private function getBooleanExpressionDepth(Expr $expr, int $depth = 0): int |
| 7869 | + { |
| 7870 | + while ( |
| 7871 | + $expr instanceof BinaryOp\BooleanOr |
| 7872 | + || $expr instanceof BinaryOp\LogicalOr |
| 7873 | + || $expr instanceof BinaryOp\BooleanAnd |
| 7874 | + || $expr instanceof BinaryOp\LogicalAnd |
| 7875 | + ) { |
| 7876 | + return $this->getBooleanExpressionDepth($expr->left, $depth + 1); |
| 7877 | + } |
| 7878 | + |
| 7879 | + return $depth; |
| 7880 | + } |
| 7881 | + |
7851 | 7882 | } |
0 commit comments