mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
added dataflow to stringy bitwise op, bitwise not op (fix 5957)
This commit is contained in:
parent
0196afc758
commit
cfaca07c6d
@ -34,6 +34,13 @@ class NonComparisonOpAnalyzer
|
||||
$stmt_type = Type::getString();
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $stmt_type);
|
||||
BinaryOpAnalyzer::addDataFlow(
|
||||
$statements_analyzer,
|
||||
$stmt,
|
||||
$stmt->left,
|
||||
$stmt->right,
|
||||
'nondivop'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Internal\Analyzer\Statements\Expression;
|
||||
|
||||
use PhpParser;
|
||||
@ -6,6 +7,8 @@ use Psalm\CodeLocation;
|
||||
use Psalm\Context;
|
||||
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
|
||||
use Psalm\Internal\Analyzer\StatementsAnalyzer;
|
||||
use Psalm\Internal\Codebase\VariableUseGraph;
|
||||
use Psalm\Internal\DataFlow\DataFlowNode;
|
||||
use Psalm\Issue\InvalidOperand;
|
||||
use Psalm\Issue\PossiblyInvalidOperand;
|
||||
use Psalm\IssueBuffer;
|
||||
@ -20,7 +23,7 @@ class BitwiseNotAnalyzer
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
PhpParser\Node\Expr\BitwiseNot $stmt,
|
||||
Context $context
|
||||
) : bool {
|
||||
): bool {
|
||||
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
@ -89,6 +92,34 @@ class BitwiseNotAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
self::addDataFlow($statements_analyzer, $stmt, $stmt->expr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function addDataFlow(
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
PhpParser\Node\Expr $stmt,
|
||||
PhpParser\Node\Expr $value,
|
||||
string $type = 'bitwisenot'
|
||||
): void {
|
||||
$result_type = $statements_analyzer->node_data->getType($stmt);
|
||||
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $result_type) {
|
||||
$var_location = new CodeLocation($statements_analyzer, $stmt);
|
||||
|
||||
$stmt_value_type = $statements_analyzer->node_data->getType($value);
|
||||
|
||||
$new_parent_node = DataFlowNode::getForAssignment($type, $var_location);
|
||||
$statements_analyzer->data_flow_graph->addNode($new_parent_node);
|
||||
$result_type->parent_nodes = [
|
||||
$new_parent_node->id => $new_parent_node,
|
||||
];
|
||||
|
||||
if ($stmt_value_type && $stmt_value_type->parent_nodes) {
|
||||
foreach ($stmt_value_type->parent_nodes as $parent_node) {
|
||||
$statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2391,6 +2391,28 @@ class UnusedVariableTest extends TestCase
|
||||
return implode("/", $arr);
|
||||
}'
|
||||
],
|
||||
'intAndBitwiseNotOperator' => [
|
||||
'<?php
|
||||
function foo() : int
|
||||
{
|
||||
$bitmask = 0x1;
|
||||
$bytes = 2;
|
||||
$ret = $bytes | ~$bitmask;
|
||||
return $ret;
|
||||
}'
|
||||
],
|
||||
'stringAndBitwiseAndOperator' => [
|
||||
'<?php
|
||||
function randomBits() : string
|
||||
{
|
||||
$bitmask = \chr(0xFF >> 1);
|
||||
|
||||
$randomBytes = random_bytes(1);
|
||||
$randomBytes[0] = $randomBytes[0] & $bitmask;
|
||||
|
||||
return $randomBytes;
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user