1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix #3709 - don’t crash on inherited __toString tainting

This commit is contained in:
Brown 2020-06-29 12:11:11 -04:00
parent 18f9e7487b
commit 45c21853e5
3 changed files with 30 additions and 3 deletions

View File

@ -4,6 +4,7 @@ namespace Psalm\Internal\Analyzer\Statements;
use PhpParser;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CastAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Taint\Sink;
use Psalm\CodeLocation;
@ -34,6 +35,17 @@ class EchoAnalyzer
ExpressionAnalyzer::analyze($statements_analyzer, $expr, $context);
$context->inside_call = false;
$expr_type = $statements_analyzer->node_data->getType($expr);
if ($expr_type) {
$expr_type = CastAnalyzer::castStringAttempt(
$statements_analyzer,
$context,
$expr,
false
);
}
if ($codebase->taint
&& $codebase->config->trackTaintsInPath($statements_analyzer->getFilePath())
) {
@ -56,7 +68,7 @@ class EchoAnalyzer
$codebase->taint->addSink($echo_param_sink);
}
if ($expr_type = $statements_analyzer->node_data->getType($expr)) {
if ($expr_type) {
if (ArgumentAnalyzer::verifyType(
$statements_analyzer,
$expr_type,

View File

@ -261,13 +261,15 @@ class CastAnalyzer
$self_class
) ?: Type::getString();
$declaring_method_id = $codebase->methods->getDeclaringMethodId($intersection_method_id);
MethodCallReturnTypeFetcher::taintMethodCallResult(
$statements_analyzer,
$return_type,
$stmt,
$stmt,
$intersection_method_id,
$intersection_method_id,
$declaring_method_id,
$intersection_type->value . '::__toString',
$context
);

View File

@ -1248,7 +1248,20 @@ class TaintTest extends TestCase
}
}
$unsafe = new MyClass();
echo (string) $unsafe;', // Psalm does not yet warn without a (string) cast.
echo $unsafe;',
'error_message' => 'TaintedInput',
],
'toStringTaintInSubclass' => [
'<?php // --taint-analysis
class TaintedBaseClass {
/** @psalm-taint-source input */
public function __toString() {
return "x";
}
}
class TaintedSubclass extends TaintedBaseClass {}
$x = new TaintedSubclass();
echo "Caught: $x\n";',
'error_message' => 'TaintedInput',
],
'implicitToStringMagic' => [