mirror of
https://github.com/github/codeql.git
synced 2026-06-23 05:37:02 +02:00
Preparatory refactor for the shared-CFG dataflow migration. Deprecates the AstNode.getAFlowNode() cached predicate on the public Python QL API and rewrites all ~140 internal callers across lib/, src/, test/, and tools/ from `expr.getAFlowNode() = cfgNode` to `cfgNode.getNode() = expr`, using ControlFlowNode.getNode() which already exists in Flow.qll. The predicate itself is preserved (with a deprecation note pointing at the new pattern) so external users do not experience churn — they can migrate at their own pace and the AST/CFG hierarchies still get the intended untangling once the deprecation eventually elapses. Semantic noop verified by: - All 361 lib/ + src/ queries compile clean. - All 122 ControlFlow + PointsTo library-tests pass. - All 64 dataflow library-tests pass. - All 113 Variables/Exceptions/Expressions/Statements/Functions/Imports/ Security/CWE-798/ModificationOfParameterWithDefault query-tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
51 lines
1.3 KiB
Plaintext
51 lines
1.3 KiB
Plaintext
/**
|
||
* @name Duplicate key in dict literal
|
||
* @description Duplicate key in dict literal. All but the last will be lost.
|
||
* @kind problem
|
||
* @tags quality
|
||
* maintainability
|
||
* useless-code
|
||
* external/cwe/cwe-561
|
||
* @problem.severity warning
|
||
* @sub-severity high
|
||
* @precision very-high
|
||
* @id py/duplicate-key-dict-literal
|
||
*/
|
||
|
||
import python
|
||
import semmle.python.strings
|
||
|
||
predicate dict_key(Dict d, Expr k, string s) {
|
||
k = d.getAKey() and
|
||
(
|
||
s = k.(Num).getN()
|
||
or
|
||
// We use <20> to mark unrepresentable characters
|
||
// so two instances of <20> may represent different strings in the source code
|
||
not "<22>" = s.charAt(_) and
|
||
exists(StringLiteral c | c = k |
|
||
s = "u\"" + c.getText() + "\"" and c.isUnicode()
|
||
or
|
||
s = "b\"" + c.getText() + "\"" and not c.isUnicode()
|
||
)
|
||
)
|
||
}
|
||
|
||
from Dict d, Expr k1, Expr k2
|
||
where
|
||
exists(string s | dict_key(d, k1, s) and dict_key(d, k2, s) and k1 != k2) and
|
||
(
|
||
exists(BasicBlock b, int i1, int i2 |
|
||
b.getNode(i1).getNode() = k1 and
|
||
b.getNode(i2).getNode() = k2 and
|
||
i1 < i2
|
||
)
|
||
or
|
||
exists(ControlFlowNode k1Cfg, ControlFlowNode k2Cfg |
|
||
k1Cfg.getNode() = k1 and k2Cfg.getNode() = k2
|
||
|
|
||
k1Cfg.getBasicBlock().strictlyDominates(k2Cfg.getBasicBlock())
|
||
)
|
||
)
|
||
select k1, "Dictionary key " + repr(k1) + " is subsequently $@.", k2, "overwritten"
|