@@ -47,6 +47,14 @@ class AnalyzedNode extends DataFlow::Node {
4747 */
4848 AnalyzedNode localFlowPred ( ) { result = getAPredecessor ( ) }
4949
50+ /**
51+ * INTERNAL. Do not use.
52+ *
53+ * Gets another data flow node whose value flows into this node in a global step
54+ * (this is, involving global variables).
55+ */
56+ AnalyzedNode globalFlowPred ( ) { none ( ) }
57+
5058 /**
5159 * Gets an abstract value that this node may evaluate to at runtime.
5260 *
@@ -57,7 +65,9 @@ class AnalyzedNode extends DataFlow::Node {
5765 * instances is also performed.
5866 */
5967 cached
60- AbstractValue getAValue ( ) { result = getALocalValue ( ) }
68+ AbstractValue getAValue ( ) {
69+ result = getALocalValue ( )
70+ }
6171
6272 /**
6373 * INTERNAL: Do not use.
@@ -68,7 +78,7 @@ class AnalyzedNode extends DataFlow::Node {
6878 * and global), IIFEs, ES6-style imports that can be resolved uniquely, and
6979 * the properties of CommonJS `module` and `exports` objects. No
7080 * tracking through the properties of object literals and function/class
71- * instances is performed.
81+ * instances is performed, other than those accounted for by `globalFlowPred` .
7282 */
7383 cached
7484 AbstractValue getALocalValue ( ) {
@@ -82,6 +92,9 @@ class AnalyzedNode extends DataFlow::Node {
8292 exists ( DataFlow:: Incompleteness cause |
8393 isIncomplete ( cause ) and result = TIndefiniteAbstractValue ( cause )
8494 )
95+ or
96+ result = globalFlowPred ( ) .getALocalValue ( ) and
97+ shouldTrackGlobally ( result )
8598 }
8699
87100 /** Gets a type inferred for this node. */
@@ -282,3 +295,8 @@ private class AnalyzedAsyncFunction extends AnalyzedFunction {
282295
283296 override AbstractValue getAReturnValue ( ) { result = TAbstractOtherObject ( ) }
284297}
298+
299+ /**
300+ * Holds if the given value should be propagated along `globalFlowPred()` edges.
301+ */
302+ private predicate shouldTrackGlobally ( AbstractValue value ) { value instanceof AbstractCallable }
0 commit comments