@@ -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 */ 
568568predicate  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