Python: Keep track of access path

This commit is contained in:
Taus
2025-08-06 14:36:47 +00:00
committed by Napalys Klicius
parent e60d0c88f1
commit 69b5853477

View File

@@ -566,10 +566,12 @@ predicate runtimeJumpStep(Node nodeFrom, Node nodeTo) {
* This supports tracking nested object field access through global variables like `app.obj.foo`.
*/
predicate globalVariableNestedFieldJumpStep(Node nodeFrom, Node nodeTo) {
exists(GlobalVariable globalVar, AttrWrite write, AttrRead read |
exists(ModuleVariableNode globalVar, AttrWrite write, AttrRead read |
// Match writes and reads on the same global variable attribute path
globalVariableAttrPath(globalVar, write.getObject()) and
globalVariableAttrPath(globalVar, read.getObject()) and
exists(string accessPath |
globalVariableAttrPath(globalVar, accessPath, write.getObject()) and
globalVariableAttrPath(globalVar, accessPath, read.getObject())
) and
write.getAttributeName() = read.getAttributeName() and
nodeFrom = write.getValue() and
nodeTo = read and
@@ -587,29 +589,32 @@ private int getMaxGlobalVariableDepth() { result = 1 }
* Holds if `node` is an attribute access path starting from global variable `globalVar`.
* Supports configurable nesting depth via getMaxGlobalVariableDepth().
*/
predicate globalVariableAttrPath(GlobalVariable globalVar, Node node) {
globalVariableAttrPathAtDepth(globalVar, node, _)
predicate globalVariableAttrPath(ModuleVariableNode globalVar, string accessPath, Node node) {
exists(int depth |
globalVariableAttrPathAtDepth(globalVar, accessPath, node, depth) and
depth > 0
)
}
/**
* Holds if `node` is an attribute access path starting from global variable `globalVar` at specific `depth`.
*/
predicate globalVariableAttrPathAtDepth(GlobalVariable globalVar, Node node, int depth) {
predicate globalVariableAttrPathAtDepth(
ModuleVariableNode globalVar, string accessPath, Node node, int depth
) {
// Base case: Direct global variable access (depth 0)
depth = 0 and
exists(NameNode name |
name.getId() = globalVar.getId() and
node.asCfgNode() = name and
name.getNode().(Name).getVariable() instanceof GlobalVariable and
not exists(ClassExpr cls | cls.getName() = globalVar.getId())
)
node in [globalVar.getARead(), globalVar.getAWrite()] and
accessPath = ""
or
// Recursive case: Nested attribute access (depth > 0)
exists(AttrRead attr, int parentDepth |
globalVariableAttrPathAtDepth(globalVar, attr.getObject(), parentDepth) and
exists(AttrRef attr, Node n, string attrName, int parentDepth, string parentAccessPath |
attr.accesses(n, attrName) and
globalVariableAttrPathAtDepth(globalVar, parentAccessPath, n, parentDepth) and
node = attr and
depth = parentDepth + 1 and
depth <= getMaxGlobalVariableDepth()
depth <= getMaxGlobalVariableDepth() and
accessPath = parentAccessPath + "." + attrName
)
}