From b5781c34e85a96a51f0ec5448a5c1e0249d92197 Mon Sep 17 00:00:00 2001 From: Mark McEver Date: Wed, 1 Feb 2023 15:41:52 -0600 Subject: [PATCH] Fixed a case where the conditional taint, specialize, & flow features were not playing nicely together --- .../Call/FunctionCallReturnTypeFetcher.php | 2 +- stubs/CoreGenericFunctions.phpstub | 60 +++++++++++++++++++ tests/TaintTest.php | 36 +++++++---- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php index bd54e0f90..0a8322e3c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php @@ -658,7 +658,7 @@ class FunctionCallReturnTypeFetcher $stmt->getArgs(), $node_location, $function_call_node, - $removed_taints, + [...$removed_taints, ...$conditionally_removed_taints], $added_taints, ); } diff --git a/stubs/CoreGenericFunctions.phpstub b/stubs/CoreGenericFunctions.phpstub index 51db73457..abd7d6219 100644 --- a/stubs/CoreGenericFunctions.phpstub +++ b/stubs/CoreGenericFunctions.phpstub @@ -816,19 +816,79 @@ function array_product(array $array) {} * @psalm-pure * * 257 is FILTER_VALIDATE_INT + * @psalm-taint-escape ($filter is 257 ? 'callable' : null) + * @psalm-taint-escape ($filter is 257 ? 'unserialize' : null) + * @psalm-taint-escape ($filter is 257 ? 'include' : null) + * @psalm-taint-escape ($filter is 257 ? 'eval' : null) + * @psalm-taint-escape ($filter is 257 ? 'ldap' : null) + * @psalm-taint-escape ($filter is 257 ? 'sql' : null) * @psalm-taint-escape ($filter is 257 ? 'html' : null) + * @psalm-taint-escape ($filter is 257 ? 'has_quotes' : null) + * @psalm-taint-escape ($filter is 257 ? 'shell' : null) + * @psalm-taint-escape ($filter is 257 ? 'ssrf' : null) + * @psalm-taint-escape ($filter is 257 ? 'file' : null) + * @psalm-taint-escape ($filter is 257 ? 'cookie' : null) + * @psalm-taint-escape ($filter is 257 ? 'header' : null) * * 258 is FILTER_VALIDATE_BOOLEAN + * @psalm-taint-escape ($filter is 258 ? 'callable' : null) + * @psalm-taint-escape ($filter is 258 ? 'unserialize' : null) + * @psalm-taint-escape ($filter is 258 ? 'include' : null) + * @psalm-taint-escape ($filter is 258 ? 'eval' : null) + * @psalm-taint-escape ($filter is 258 ? 'ldap' : null) + * @psalm-taint-escape ($filter is 258 ? 'sql' : null) * @psalm-taint-escape ($filter is 258 ? 'html' : null) + * @psalm-taint-escape ($filter is 258 ? 'has_quotes' : null) + * @psalm-taint-escape ($filter is 258 ? 'shell' : null) + * @psalm-taint-escape ($filter is 258 ? 'ssrf' : null) + * @psalm-taint-escape ($filter is 258 ? 'file' : null) + * @psalm-taint-escape ($filter is 258 ? 'cookie' : null) + * @psalm-taint-escape ($filter is 258 ? 'header' : null) * * 259 is FILTER_VALIDATE_FLOAT + * @psalm-taint-escape ($filter is 259 ? 'callable' : null) + * @psalm-taint-escape ($filter is 259 ? 'unserialize' : null) + * @psalm-taint-escape ($filter is 259 ? 'include' : null) + * @psalm-taint-escape ($filter is 259 ? 'eval' : null) + * @psalm-taint-escape ($filter is 259 ? 'ldap' : null) + * @psalm-taint-escape ($filter is 259 ? 'sql' : null) * @psalm-taint-escape ($filter is 259 ? 'html' : null) + * @psalm-taint-escape ($filter is 259 ? 'has_quotes' : null) + * @psalm-taint-escape ($filter is 259 ? 'shell' : null) + * @psalm-taint-escape ($filter is 259 ? 'ssrf' : null) + * @psalm-taint-escape ($filter is 259 ? 'file' : null) + * @psalm-taint-escape ($filter is 259 ? 'cookie' : null) + * @psalm-taint-escape ($filter is 259 ? 'header' : null) * * 519 is FILTER_SANITIZE_NUMBER_INT + * @psalm-taint-escape ($filter is 519 ? 'callable' : null) + * @psalm-taint-escape ($filter is 519 ? 'unserialize' : null) + * @psalm-taint-escape ($filter is 519 ? 'include' : null) + * @psalm-taint-escape ($filter is 519 ? 'eval' : null) + * @psalm-taint-escape ($filter is 519 ? 'ldap' : null) + * @psalm-taint-escape ($filter is 519 ? 'sql' : null) * @psalm-taint-escape ($filter is 519 ? 'html' : null) + * @psalm-taint-escape ($filter is 519 ? 'has_quotes' : null) + * @psalm-taint-escape ($filter is 519 ? 'shell' : null) + * @psalm-taint-escape ($filter is 519 ? 'ssrf' : null) + * @psalm-taint-escape ($filter is 519 ? 'file' : null) + * @psalm-taint-escape ($filter is 519 ? 'cookie' : null) + * @psalm-taint-escape ($filter is 519 ? 'header' : null) * * 520 is FILTER_SANITIZE_NUMBER_FLOAT + * @psalm-taint-escape ($filter is 520 ? 'callable' : null) + * @psalm-taint-escape ($filter is 520 ? 'unserialize' : null) + * @psalm-taint-escape ($filter is 520 ? 'include' : null) + * @psalm-taint-escape ($filter is 520 ? 'eval' : null) + * @psalm-taint-escape ($filter is 520 ? 'ldap' : null) + * @psalm-taint-escape ($filter is 520 ? 'sql' : null) * @psalm-taint-escape ($filter is 520 ? 'html' : null) + * @psalm-taint-escape ($filter is 520 ? 'has_quotes' : null) + * @psalm-taint-escape ($filter is 520 ? 'shell' : null) + * @psalm-taint-escape ($filter is 520 ? 'ssrf' : null) + * @psalm-taint-escape ($filter is 520 ? 'file' : null) + * @psalm-taint-escape ($filter is 520 ? 'cookie' : null) + * @psalm-taint-escape ($filter is 520 ? 'header' : null) * * @psalm-flow ($value, $filter, $options) -> return */ diff --git a/tests/TaintTest.php b/tests/TaintTest.php index 4034e9dc0..e0610c802 100644 --- a/tests/TaintTest.php +++ b/tests/TaintTest.php @@ -230,19 +230,31 @@ class TaintTest extends TestCase echo $a; }', ], - 'taintFilterVarInt' => [ + 'taintFilterVar' => [ 'code' => ' [ - 'code' => ' [ - 'code' => ' [ 'code' => '