1
0
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:
Ruslan Karimov 2021-07-12 22:09:20 +05:00
parent 0196afc758
commit cfaca07c6d
3 changed files with 61 additions and 1 deletions

View File

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

View File

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

View File

@ -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;
}'
],
];
}