diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php index bc6b0e216..aac7cdb26 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php @@ -122,8 +122,6 @@ class ArrayAssignmentAnalyzer // fall through } } - - return null; } $child_stmts = array_reverse($child_stmts); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php index ebd9e41f8..dc582dc6a 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php @@ -49,7 +49,8 @@ class InstancePropertyFetchAnalyzer public static function analyze( StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, - Context $context + Context $context, + bool $in_assignment = false ) : bool { if (!$stmt->name instanceof PhpParser\Node\Identifier) { if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->name, $context) === false) { @@ -182,7 +183,8 @@ class InstancePropertyFetchAnalyzer $stmt, $stmt_type, $property_id, - $codebase->classlike_storage_provider->get($lhs_type_part->value) + $codebase->classlike_storage_provider->get($lhs_type_part->value), + $in_assignment ); $codebase->properties->propertyExists( @@ -569,7 +571,8 @@ class InstancePropertyFetchAnalyzer $stmt, $stmt_type, $property_id, - $class_storage + $class_storage, + $in_assignment ); continue; } @@ -680,7 +683,8 @@ class InstancePropertyFetchAnalyzer $stmt, $stmt_type, $property_id, - $class_storage + $class_storage, + $in_assignment ); continue; } @@ -918,7 +922,8 @@ class InstancePropertyFetchAnalyzer $stmt, $class_property_type, $property_id, - $class_storage + $class_storage, + $in_assignment ); if ($stmt_type = $statements_analyzer->node_data->getType($stmt)) { @@ -1064,7 +1069,8 @@ class InstancePropertyFetchAnalyzer PhpParser\Node\Expr\PropertyFetch $stmt, Type\Union $type, string $property_id, - \Psalm\Storage\ClassLikeStorage $class_storage + \Psalm\Storage\ClassLikeStorage $class_storage, + bool $in_assignment ) : void { $codebase = $statements_analyzer->getCodebase(); @@ -1145,7 +1151,11 @@ class InstancePropertyFetchAnalyzer $codebase->taint->addTaintNode($property_node); - $codebase->taint->addPath($property_node, $localized_property_node, 'property-fetch'); + if ($in_assignment) { + $codebase->taint->addPath($localized_property_node, $property_node, 'property-assignment'); + } else { + $codebase->taint->addPath($property_node, $localized_property_node, 'property-fetch'); + } $type->parent_nodes[] = $localized_property_node; } diff --git a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php index 135cc280b..9e71d5cd4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php @@ -205,7 +205,8 @@ class ExpressionAnalyzer return Expression\Fetch\InstancePropertyFetchAnalyzer::analyze( $statements_analyzer, $stmt, - $context + $context, + $array_assignment ); } diff --git a/src/Psalm/Internal/Diff/ClassStatementsDiffer.php b/src/Psalm/Internal/Diff/ClassStatementsDiffer.php index 27ba909ad..637ff90db 100644 --- a/src/Psalm/Internal/Diff/ClassStatementsDiffer.php +++ b/src/Psalm/Internal/Diff/ClassStatementsDiffer.php @@ -95,6 +95,7 @@ class ClassStatementsDiffer extends AstDiffer $start_diff = $b_start - $a_start; $line_diff = $b->getLine() - $a->getLine(); + /** @psalm-suppress MixedArrayAssignment */ $diff_map[] = [$a_start, $a_end, $start_diff, $line_diff]; return true; @@ -172,6 +173,7 @@ class ClassStatementsDiffer extends AstDiffer } if (!$signature_change && !$body_change) { + /** @psalm-suppress MixedArrayAssignment */ $diff_map[] = [$a_start, $a_end, $b_start - $a_start, $b->getLine() - $a->getLine()]; } diff --git a/src/Psalm/Internal/Taint/Taintable.php b/src/Psalm/Internal/Taint/Taintable.php index f535ab61b..d46877672 100644 --- a/src/Psalm/Internal/Taint/Taintable.php +++ b/src/Psalm/Internal/Taint/Taintable.php @@ -69,7 +69,7 @@ abstract class Taintable ?CodeLocation $arg_location, ?CodeLocation $code_location = null ) { - $arg_id = $method_id . '#' . ($argument_offset + 1); + $arg_id = strtolower($method_id) . '#' . ($argument_offset + 1); $label = $cased_method_id . '#' . ($argument_offset + 1); @@ -80,7 +80,7 @@ abstract class Taintable } return new static( - \strtolower($arg_id), + $arg_id, $label, $arg_location, $specialization_key diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index f0f6ddbea..879b670aa 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -544,6 +544,7 @@ class ArrayAccessTest extends TestCase * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedOperand + * @psalm-suppress MixedArrayAssignment * @param mixed[] $line */ function _renderCells(array $line): void { diff --git a/tests/TaintTest.php b/tests/TaintTest.php index d899d980b..d5e1361d3 100644 --- a/tests/TaintTest.php +++ b/tests/TaintTest.php @@ -1239,6 +1239,25 @@ class TaintTest extends TestCase }', 'error_message' => 'TaintedInput', ], + 'magicPropertyType' => [ + 'params[$a]; + } + + public function __set(string $a, $value) { + $this->params[$a] = $value; + } + } + + $m = new Magic(); + $m->taint = $_GET["input"]; + echo $m->taint;', + 'error_message' => 'TaintedInput', + ], ]; } }