1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #3668 - taint property types for magic properties without @property

This commit is contained in:
Brown 2020-06-25 00:24:37 -04:00
parent dd25b81d3a
commit b84cf74754
7 changed files with 43 additions and 12 deletions

View File

@ -122,8 +122,6 @@ class ArrayAssignmentAnalyzer
// fall through
}
}
return null;
}
$child_stmts = array_reverse($child_stmts);

View File

@ -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;
}

View File

@ -205,7 +205,8 @@ class ExpressionAnalyzer
return Expression\Fetch\InstancePropertyFetchAnalyzer::analyze(
$statements_analyzer,
$stmt,
$context
$context,
$array_assignment
);
}

View File

@ -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()];
}

View File

@ -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

View File

@ -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 {

View File

@ -1239,6 +1239,25 @@ class TaintTest extends TestCase
}',
'error_message' => 'TaintedInput',
],
'magicPropertyType' => [
'<?php
class Magic {
private $params = [];
public function __get(string $a) {
return $this->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',
],
];
}
}