mirror of
https://github.com/danog/psalm.git
synced 2024-12-12 17:27:28 +01:00
Reduce size of data flow graph when analysing array assignments
This commit is contained in:
parent
4cb8e86737
commit
e27cbfba57
@ -792,17 +792,33 @@ class ArrayAssignmentAnalyzer
|
||||
&& ($statements_analyzer->data_flow_graph instanceof VariableUseGraph
|
||||
|| !\in_array('TaintedInput', $statements_analyzer->getSuppressedIssues()))
|
||||
) {
|
||||
if (!$stmt_type->parent_nodes) {
|
||||
$var_location = new \Psalm\CodeLocation($statements_analyzer->getSource(), $expr->var);
|
||||
$var_location = new \Psalm\CodeLocation($statements_analyzer->getSource(), $expr->var);
|
||||
|
||||
$parent_node = \Psalm\Internal\DataFlow\DataFlowNode::getForAssignment(
|
||||
$var_var_id ?: 'assignment',
|
||||
$var_location
|
||||
$parent_node = \Psalm\Internal\DataFlow\DataFlowNode::getForAssignment(
|
||||
$var_var_id ?: 'assignment',
|
||||
$var_location
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($parent_node);
|
||||
|
||||
$old_parent_nodes = $stmt_type->parent_nodes;
|
||||
|
||||
$stmt_type->parent_nodes = [$parent_node->id => $parent_node];
|
||||
|
||||
foreach ($old_parent_nodes as $old_parent_node) {
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$old_parent_node,
|
||||
$parent_node,
|
||||
'='
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($parent_node);
|
||||
|
||||
$stmt_type->parent_nodes = [$parent_node->id => $parent_node];
|
||||
if ($stmt_type->by_ref) {
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
$parent_node,
|
||||
$old_parent_node,
|
||||
'='
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($stmt_type->parent_nodes as $parent_node) {
|
||||
|
@ -1235,13 +1235,16 @@ class InstancePropertyAssignmentAnalyzer
|
||||
return;
|
||||
}
|
||||
|
||||
$code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
|
||||
$var_property_id = ExpressionIdentifier::getArrayVarId(
|
||||
$stmt,
|
||||
null,
|
||||
$statements_analyzer
|
||||
);
|
||||
|
||||
$localized_property_node = new DataFlowNode(
|
||||
$property_id . '-' . $code_location->file_name . ':' . $code_location->raw_file_start,
|
||||
$property_id,
|
||||
$code_location,
|
||||
null
|
||||
$localized_property_node = DataFlowNode::getForAssignment(
|
||||
$var_property_id
|
||||
?: $property_id . '-' . $property_location->file_name . ':' . $property_location->raw_file_start,
|
||||
$property_location
|
||||
);
|
||||
|
||||
$data_flow_graph->addNode($localized_property_node);
|
||||
|
@ -1267,7 +1267,7 @@ class ArgumentAnalyzer
|
||||
$function_param->location
|
||||
);
|
||||
|
||||
if (strpos($cased_method_id, '::')) {
|
||||
if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && strpos($cased_method_id, '::')) {
|
||||
[$fq_classlike_name, $cased_method_name] = explode('::', $cased_method_id);
|
||||
$method_name = strtolower($cased_method_name);
|
||||
$class_storage = $codebase->classlike_storage_provider->get($fq_classlike_name);
|
||||
|
@ -1700,6 +1700,8 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['method_exists']) {
|
||||
@ -1714,7 +1716,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
} else {
|
||||
$context->check_methods = false;
|
||||
}
|
||||
} elseif ($function_name->parts === ['class_exists']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['class_exists']) {
|
||||
if ($first_arg) {
|
||||
if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
|
||||
if (!$codebase->classlikes->classExists($first_arg->value->value)) {
|
||||
@ -1732,7 +1738,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($function_name->parts === ['interface_exists']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['interface_exists']) {
|
||||
if ($first_arg) {
|
||||
if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
|
||||
$context->phantom_classes[strtolower($first_arg->value->value)] = true;
|
||||
@ -1748,13 +1758,21 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($function_name->parts === ['file_exists'] && $first_arg) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['file_exists'] && $first_arg) {
|
||||
$var_id = ExpressionIdentifier::getArrayVarId($first_arg->value, null);
|
||||
|
||||
if ($var_id) {
|
||||
$context->phantom_files[$var_id] = true;
|
||||
}
|
||||
} elseif ($function_name->parts === ['extension_loaded']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['extension_loaded']) {
|
||||
if ($first_arg
|
||||
&& $first_arg->value instanceof PhpParser\Node\Scalar\String_
|
||||
) {
|
||||
@ -1764,14 +1782,27 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
$context->check_classes = false;
|
||||
}
|
||||
}
|
||||
} elseif ($function_name->parts === ['function_exists']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['function_exists']) {
|
||||
$context->check_functions = false;
|
||||
} elseif ($function_name->parts === ['is_callable']) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['is_callable']) {
|
||||
$context->check_methods = false;
|
||||
$context->check_functions = false;
|
||||
} elseif ($function_name->parts === ['defined']) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['defined']) {
|
||||
$context->check_consts = false;
|
||||
} elseif ($function_name->parts === ['extract']) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['extract']) {
|
||||
$context->check_variables = false;
|
||||
|
||||
foreach ($context->vars_in_scope as $var_id => $_) {
|
||||
@ -1786,7 +1817,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
$context->assigned_var_ids[$var_id] = (int) $stmt->getAttribute('startFilePos');
|
||||
$context->possibly_assigned_var_ids[$var_id] = true;
|
||||
}
|
||||
} elseif ($function_name->parts === ['compact']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['compact']) {
|
||||
$all_args_string_literals = true;
|
||||
$new_items = [];
|
||||
|
||||
@ -1823,7 +1858,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
$statements_analyzer->node_data->setType($stmt, $arr_type);
|
||||
}
|
||||
}
|
||||
} elseif ($function_name->parts === ['func_get_args']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['func_get_args']) {
|
||||
$source = $statements_analyzer->getSource();
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
@ -1839,7 +1878,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (strtolower($function_name->parts[0]) === 'var_dump'
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strtolower($function_name->parts[0]) === 'var_dump'
|
||||
|| strtolower($function_name->parts[0]) === 'shell_exec') {
|
||||
if (IssueBuffer::accepts(
|
||||
new ForbiddenCode(
|
||||
@ -1850,7 +1893,9 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
)) {
|
||||
// continue
|
||||
}
|
||||
} elseif (isset($codebase->config->forbidden_functions[strtolower((string) $function_name)])) {
|
||||
}
|
||||
|
||||
if (isset($codebase->config->forbidden_functions[strtolower((string) $function_name)])) {
|
||||
if (IssueBuffer::accepts(
|
||||
new ForbiddenCode(
|
||||
'You have forbidden the use of ' . $function_name,
|
||||
@ -1860,7 +1905,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
)) {
|
||||
// continue
|
||||
}
|
||||
} elseif ($function_name->parts === ['define']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['define']) {
|
||||
if ($first_arg) {
|
||||
$fq_const_name = ConstFetchAnalyzer::getConstName(
|
||||
$first_arg->value,
|
||||
@ -1886,7 +1935,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
} else {
|
||||
$context->check_consts = false;
|
||||
}
|
||||
} elseif ($function_name->parts === ['constant']) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($function_name->parts === ['constant']) {
|
||||
if ($first_arg) {
|
||||
$fq_const_name = ConstFetchAnalyzer::getConstName(
|
||||
$first_arg->value,
|
||||
@ -1910,7 +1963,9 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
} else {
|
||||
$context->check_consts = false;
|
||||
}
|
||||
} elseif ($first_arg
|
||||
}
|
||||
|
||||
if ($first_arg
|
||||
&& $function_id
|
||||
&& strpos($function_id, 'is_') === 0
|
||||
&& $function_id !== 'is_a'
|
||||
@ -1951,7 +2006,11 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
);
|
||||
}
|
||||
} elseif ($first_arg && $function_id === 'strtolower') {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($first_arg && $function_id === 'strtolower') {
|
||||
$first_arg_type = $statements_analyzer->node_data->getType($first_arg->value);
|
||||
|
||||
if ($first_arg_type
|
||||
|
@ -840,13 +840,16 @@ class AtomicPropertyFetchAnalyzer
|
||||
$type->parent_nodes = [$property_node->id => $property_node];
|
||||
}
|
||||
} else {
|
||||
$code_location = new CodeLocation($statements_analyzer, $stmt->name);
|
||||
$var_property_id = ExpressionIdentifier::getArrayVarId(
|
||||
$stmt,
|
||||
null,
|
||||
$statements_analyzer
|
||||
);
|
||||
|
||||
$localized_property_node = new DataFlowNode(
|
||||
$property_id . '-' . $code_location->file_name . ':' . $code_location->raw_file_start,
|
||||
$property_id,
|
||||
$code_location,
|
||||
null
|
||||
$localized_property_node = DataFlowNode::getForAssignment(
|
||||
$var_property_id
|
||||
?: $property_id . '-' . $property_location->file_name . ':' . $property_location->raw_file_start,
|
||||
$property_location
|
||||
);
|
||||
|
||||
$data_flow_graph->addNode($localized_property_node);
|
||||
@ -866,7 +869,7 @@ class AtomicPropertyFetchAnalyzer
|
||||
$data_flow_graph->addPath($property_node, $localized_property_node, 'property-fetch');
|
||||
}
|
||||
|
||||
$type->parent_nodes[$localized_property_node->id] = $localized_property_node;
|
||||
$type->parent_nodes = [$localized_property_node->id => $localized_property_node];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user