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

Fix #3675 - add taints to filter_var return

Doesn’t yet take callback into account
This commit is contained in:
Brown 2020-06-25 13:24:26 -04:00
parent 9e7650586b
commit 9837a60853
2 changed files with 48 additions and 4 deletions

View File

@ -6,6 +6,7 @@ use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
use Psalm\Type;
use Psalm\Internal\Taint\TaintNode;
class FilterVarReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturnTypeProviderInterface
{
@ -25,9 +26,11 @@ class FilterVarReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturnTy
CodeLocation $code_location
) : Type\Union {
if (!$statements_source instanceof \Psalm\Internal\Analyzer\StatementsAnalyzer) {
return Type::getMixed();
throw new \UnexpectedValueException();
}
$filter_type = null;
if (isset($call_args[1])
&& ($second_arg_type = $statements_source->node_data->getType($call_args[1]->value))
&& $second_arg_type->isSingleIntLiteral()
@ -109,10 +112,44 @@ class FilterVarReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturnTy
if (!$has_object_like && !$filter_null && $filter_type) {
$filter_type->addType(new Type\Atomic\TFalse);
}
return $filter_type ?: Type::getMixed();
}
return Type::getMixed();
if (!$filter_type) {
$filter_type = Type::getMixed();
}
$codebase = $statements_source->getCodebase();
if ($codebase->taint) {
$function_return_sink = TaintNode::getForMethodReturn(
$function_id,
$function_id,
null,
$code_location
);
$codebase->taint->addTaintNode($function_return_sink);
$function_param_sink = TaintNode::getForMethodArgument(
$function_id,
$function_id,
0,
null,
$code_location
);
$codebase->taint->addTaintNode($function_param_sink);
$codebase->taint->addPath(
$function_param_sink,
$function_return_sink,
'arg'
);
$filter_type->parent_nodes = [$function_return_sink];
}
return $filter_type;
}
}

View File

@ -1317,6 +1317,13 @@ class TaintTest extends TestCase
echo $get["test"];',
'error_message' => 'TaintedInput',
],
'taintFilterVar' => [
'<?php
$get = filter_var($_GET, FILTER_CALLBACK, ["options" => "trim"]);
echo $get["test"];',
'error_message' => 'TaintedInput',
],
];
}
}