Skip to content

Commit 69b5853

Browse files
tausbnNapalys
authored andcommitted
Python: Keep track of access path
1 parent e60d0c8 commit 69b5853

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,12 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) {
566566
* This supports tracking nested object field access through global variables like `app.obj.foo`.
567567
*/
568568
predicate globalVariableNestedFieldJumpStep(Node nodeFrom, Node nodeTo) {
569-
exists(GlobalVariable globalVar, AttrWrite write, AttrRead read |
569+
exists(ModuleVariableNode globalVar, AttrWrite write, AttrRead read |
570570
// Match writes and reads on the same global variable attribute path
571-
globalVariableAttrPath(globalVar, write.getObject()) and
572-
globalVariableAttrPath(globalVar, read.getObject()) and
571+
exists(string accessPath |
572+
globalVariableAttrPath(globalVar, accessPath, write.getObject()) and
573+
globalVariableAttrPath(globalVar, accessPath, read.getObject())
574+
) and
573575
write.getAttributeName() = read.getAttributeName() and
574576
nodeFrom = write.getValue() and
575577
nodeTo = read and
@@ -587,29 +589,32 @@ private int getMaxGlobalVariableDepth() { result = 1 }
587589
* Holds if `node` is an attribute access path starting from global variable `globalVar`.
588590
* Supports configurable nesting depth via getMaxGlobalVariableDepth().
589591
*/
590-
predicate globalVariableAttrPath(GlobalVariable globalVar, Node node) {
591-
globalVariableAttrPathAtDepth(globalVar, node, _)
592+
predicate globalVariableAttrPath(ModuleVariableNode globalVar, string accessPath, Node node) {
593+
exists(int depth |
594+
globalVariableAttrPathAtDepth(globalVar, accessPath, node, depth) and
595+
depth > 0
596+
)
592597
}
593598

594599
/**
595600
* Holds if `node` is an attribute access path starting from global variable `globalVar` at specific `depth`.
596601
*/
597-
predicate globalVariableAttrPathAtDepth(GlobalVariable globalVar, Node node, int depth) {
602+
predicate globalVariableAttrPathAtDepth(
603+
ModuleVariableNode globalVar, string accessPath, Node node, int depth
604+
) {
598605
// Base case: Direct global variable access (depth 0)
599606
depth = 0 and
600-
exists(NameNode name |
601-
name.getId() = globalVar.getId() and
602-
node.asCfgNode() = name and
603-
name.getNode().(Name).getVariable() instanceof GlobalVariable and
604-
not exists(ClassExpr cls | cls.getName() = globalVar.getId())
605-
)
607+
node in [globalVar.getARead(), globalVar.getAWrite()] and
608+
accessPath = ""
606609
or
607610
// Recursive case: Nested attribute access (depth > 0)
608-
exists(AttrRead attr, int parentDepth |
609-
globalVariableAttrPathAtDepth(globalVar, attr.getObject(), parentDepth) and
611+
exists(AttrRef attr, Node n, string attrName, int parentDepth, string parentAccessPath |
612+
attr.accesses(n, attrName) and
613+
globalVariableAttrPathAtDepth(globalVar, parentAccessPath, n, parentDepth) and
610614
node = attr and
611615
depth = parentDepth + 1 and
612-
depth <= getMaxGlobalVariableDepth()
616+
depth <= getMaxGlobalVariableDepth() and
617+
accessPath = parentAccessPath + "." + attrName
613618
)
614619
}
615620

0 commit comments

Comments
 (0)