Skip to content

Commit

Permalink
Fix vimeo#4266 - prevent OOM when analysing closure unioned with invo…
Browse files Browse the repository at this point in the history
…kable class
  • Loading branch information
muglug authored and danog committed Jan 29, 2021
1 parent a4b6cb8 commit f63a40f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
Expand Up @@ -695,7 +695,8 @@ private static function getAnalyzeNamedExpression(
$stmt,
$real_stmt,
$function_name,
$context
$context,
$var_type_part
);
}
}
Expand Down Expand Up @@ -746,7 +747,8 @@ private static function analyzeInvokeCall(
PhpParser\Node\Expr\FuncCall $stmt,
PhpParser\Node\Expr\FuncCall $real_stmt,
PhpParser\Node\Expr $function_name,
Context $context
Context $context,
Type\Atomic $atomic_type
) : void {
$old_data_provider = $statements_analyzer->node_data;

Expand All @@ -772,6 +774,8 @@ private static function analyzeInvokeCall(
$statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
}

$statements_analyzer->node_data->setType($function_name, new Type\Union([$atomic_type]));

\Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer::analyze(
$statements_analyzer,
$fake_method_call,
Expand Down
Expand Up @@ -47,7 +47,15 @@ public static function analyze(
$was_inside_use = $context->inside_use;
$context->inside_use = true;

if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === false) {
$existing_stmt_var_type = null;

if (!$real_method_call) {
$existing_stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
}

if ($existing_stmt_var_type) {
$statements_analyzer->node_data->setType($stmt->var, $existing_stmt_var_type);
} elseif (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === false) {
return false;
}

Expand Down
32 changes: 32 additions & 0 deletions tests/FileManipulation/ReturnTypeManipulationTest.php
Expand Up @@ -575,6 +575,38 @@ public function getMe() {
false,
true,
],
'dontOOM' => [
'<?php
class FC {
public function __invoke() : void {}
}
function foo(): string {
if (rand(0, 1)) {
$cb = new FC();
} else {
$cb = function() {};
}
$cb();
}',
'<?php
class FC {
public function __invoke() : void {}
}
function foo(): string {
if (rand(0, 1)) {
$cb = new FC();
} else {
$cb = function() {};
}
$cb();
}',
'7.3',
['InvalidReturnType'],
false,
true,
],
];
}
}

0 comments on commit f63a40f

Please sign in to comment.