@@ -132,7 +132,7 @@ module API {
132132 */
133133 pragma [ inline]
134134 DataFlow:: Node getAValueReachableFromSource ( ) {
135- Impl:: trackUseNode ( this .asSource ( ) ) . flowsTo ( result )
135+ Impl:: trackUseNode ( this .asSource ( ) , result . getALocalSource ( ) )
136136 }
137137
138138 /**
@@ -171,7 +171,7 @@ module API {
171171 CallNode getMaybePromisifiedCall ( ) {
172172 result = this .getACall ( )
173173 or
174- result = Impl:: getAPromisifiedInvocation ( this , _, _)
174+ Impl:: getAPromisifiedInvocation ( this , _, _, result )
175175 }
176176
177177 /**
@@ -210,7 +210,7 @@ module API {
210210 * This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow.
211211 * See `asSink()` for examples.
212212 */
213- DataFlow:: Node getAValueReachingSink ( ) { result = Impl:: trackDefNode ( this .asSink ( ) ) }
213+ DataFlow:: Node getAValueReachingSink ( ) { Impl:: trackDefNode ( this .asSink ( ) , result ) }
214214
215215 /**
216216 * Gets a node representing member `m` of this API component.
@@ -855,7 +855,7 @@ module API {
855855 )
856856 or
857857 exists ( DataFlow:: Node def , DataFlow:: SourceNode pred |
858- rhs ( base , def ) and pred = trackDefNode ( def )
858+ rhs ( base , def ) and trackDefNode ( def , pred )
859859 |
860860 // from `x` to a definition of `x.prop`
861861 exists ( DataFlow:: PropWrite pw | pw = pred .getAPropertyWrite ( ) |
@@ -956,8 +956,11 @@ module API {
956956 lbl = Label:: spreadArgument ( i )
957957 )
958958 or
959- exists ( DataFlow:: SourceNode src , DataFlow:: PropWrite pw |
960- use ( base , src ) and pw = trackUseNode ( src ) .getAPropertyWrite ( ) and rhs = pw .getRhs ( )
959+ exists ( DataFlow:: SourceNode src , DataFlow:: SourceNode mid , DataFlow:: PropWrite pw |
960+ use ( base , src ) and
961+ trackUseNode ( src , mid ) and
962+ pw = mid .getAPropertyWrite ( ) and
963+ rhs = pw .getRhs ( )
961964 |
962965 lbl = Label:: memberFromRef ( pw )
963966 )
@@ -1099,7 +1102,7 @@ module API {
10991102 )
11001103 or
11011104 exists ( DataFlow:: SourceNode src , DataFlow:: SourceNode pred |
1102- use ( base , src ) and pred = trackUseNode ( src )
1105+ use ( base , src ) and trackUseNode ( src , pred )
11031106 |
11041107 lbl = Label:: instance ( ) and
11051108 ref = pred .getAnInstantiation ( )
@@ -1133,7 +1136,7 @@ module API {
11331136 )
11341137 or
11351138 exists ( DataFlow:: Node def , DataFlow:: FunctionNode fn |
1136- rhs ( base , def ) and fn = trackDefNode ( def )
1139+ rhs ( base , def ) and trackDefNode ( def , fn )
11371140 |
11381141 exists ( int i |
11391142 lbl = Label:: parameter ( i ) and
@@ -1145,7 +1148,7 @@ module API {
11451148 )
11461149 or
11471150 exists ( DataFlow:: Node def , DataFlow:: ClassNode cls , int i |
1148- rhs ( base , def ) and cls = trackDefNode ( def )
1151+ rhs ( base , def ) and trackDefNode ( def , cls )
11491152 |
11501153 lbl = Label:: parameter ( i ) and
11511154 ref = cls .getConstructor ( ) .getParameter ( i )
@@ -1188,7 +1191,7 @@ module API {
11881191 private predicate useNodeFlowsToDecorator ( TApiNode base , Decorator decorator ) {
11891192 exists ( DataFlow:: SourceNode decoratorSrc |
11901193 use ( base , decoratorSrc ) and
1191- trackUseNode ( decoratorSrc ) . flowsToExpr ( decorator . getExpression ( ) )
1194+ trackUseNode ( decoratorSrc , decorator . getExpression ( ) . flow ( ) . getALocalSource ( ) )
11921195 )
11931196 }
11941197
@@ -1271,9 +1274,9 @@ module API {
12711274 private predicate needsDefNode ( DataFlow:: ClassNode cls ) {
12721275 hasSemantics ( cls ) and
12731276 (
1274- cls = trackDefNode ( _)
1277+ trackDefNode ( _, cls )
12751278 or
1276- cls .getAnInstanceReference ( ) = trackDefNode ( _ )
1279+ trackDefNode ( _ , cls .getAnInstanceReference ( ) )
12771280 or
12781281 needsDefNode ( cls .getADirectSubClass ( ) )
12791282 or
@@ -1296,8 +1299,8 @@ module API {
12961299 exists ( string m , Module mod | nd = MkModuleExport ( m ) and mod = importableModule ( m ) |
12971300 ref = DataFlow:: exportsVarNode ( mod )
12981301 or
1299- exists ( DataFlow:: Node base | use ( MkModuleDef ( m ) , base ) |
1300- ref = trackUseNode ( base ) .getAPropertyRead ( "exports" )
1302+ exists ( DataFlow:: Node base , DataFlow :: SourceNode mid | use ( MkModuleDef ( m ) , base ) |
1303+ trackUseNode ( base , mid ) and ref = mid .getAPropertyRead ( "exports" )
13011304 )
13021305 )
13031306 or
@@ -1415,34 +1418,36 @@ module API {
14151418 }
14161419
14171420 /**
1418- * Gets a node that is inter-procedurally reachable from `nd`, which is a use of some node.
1421+ * Holds if `target` is inter-procedurally reachable from `nd`, which is a use of some node.
14191422 */
1420- DataFlow:: SourceNode trackUseNode ( DataFlow:: SourceNode nd ) {
1421- result = trackUseNode ( nd , false , 0 , "" )
1423+ predicate trackUseNode ( DataFlow:: SourceNode nd , DataFlow:: SourceNode target ) {
1424+ target = trackUseNode ( nd , false , 0 , "" )
14221425 }
14231426
14241427 /**
14251428 * Gets a node whose forward tracking reaches `nd` in some state (e.g. possibly inside a content at this point).
14261429 */
1427- DataFlow:: SourceNode trackUseNodeAnyState ( DataFlow:: SourceNode nd ) {
1428- result = trackUseNode ( nd , _, _, _, _)
1430+ predicate trackUseNodeAnyState ( DataFlow:: SourceNode nd , DataFlow:: SourceNode target ) {
1431+ target = trackUseNode ( nd , _, _, _, _)
14291432 }
14301433
1431- private DataFlow:: SourceNode trackDefNode ( DataFlow:: Node nd , DataFlow:: TypeBackTracker t ) {
1434+ private predicate trackDefNode (
1435+ DataFlow:: Node nd , DataFlow:: TypeBackTracker t , DataFlow:: SourceNode target
1436+ ) {
14321437 t .start ( ) and
14331438 rhs ( _, nd ) and
1434- result = nd .getALocalSource ( )
1439+ target = nd .getALocalSource ( )
14351440 or
14361441 // additional backwards step from `require('m')` to `exports` or `module.exports` in m
1437- exists ( Import imp | imp . getImportedModuleNodeStrict ( ) = trackDefNode ( nd , t .continue ( ) ) |
1438- result = DataFlow:: exportsVarNode ( imp .getImportedModule ( ) )
1442+ exists ( Import imp | trackDefNode ( nd , t .continue ( ) , imp . getImportedModuleNodeStrict ( ) ) |
1443+ target = DataFlow:: exportsVarNode ( imp .getImportedModule ( ) )
14391444 or
1440- result = DataFlow:: moduleVarNode ( imp .getImportedModule ( ) ) .getAPropertyRead ( "exports" )
1445+ target = DataFlow:: moduleVarNode ( imp .getImportedModule ( ) ) .getAPropertyRead ( "exports" )
14411446 )
14421447 or
14431448 exists ( ObjectExpr obj |
1444- obj = trackDefNode ( nd , t .continue ( ) ) . asExpr ( ) and
1445- result =
1449+ trackDefNode ( nd , t .continue ( ) , obj . flow ( ) ) and
1450+ target =
14461451 obj .getAProperty ( )
14471452 .( SpreadProperty )
14481453 .getInit ( )
@@ -1452,7 +1457,7 @@ module API {
14521457 .getALocalSource ( )
14531458 )
14541459 or
1455- t = defStep ( nd , result )
1460+ t = defStep ( nd , target )
14561461 }
14571462
14581463 /**
@@ -1465,7 +1470,7 @@ module API {
14651470 pragma [ noopt]
14661471 private DataFlow:: TypeBackTracker defStep ( DataFlow:: Node nd , DataFlow:: SourceNode prev ) {
14671472 exists ( DataFlow:: TypeBackTracker t , StepSummary summary , DataFlow:: Node next |
1468- next = trackDefNode ( nd , t ) and
1473+ trackDefNode ( nd , t , next ) and
14691474 StepSummary:: step ( prev , next , summary ) and
14701475 result = t .prepend ( summary ) and
14711476 // Block argument-passing into 'this' when it determines the call target
@@ -1474,16 +1479,18 @@ module API {
14741479 }
14751480
14761481 /**
1477- * Gets a node that inter-procedurally flows into `nd`, which is a definition of some node.
1482+ * Holds if `target` inter-procedurally flows into `nd`, which is a definition of some node.
14781483 */
1479- DataFlow :: SourceNode trackDefNode ( DataFlow:: Node nd ) {
1480- result = trackDefNode ( nd , DataFlow:: TypeBackTracker:: end ( ) )
1484+ predicate trackDefNode ( DataFlow:: Node nd , DataFlow :: SourceNode target ) {
1485+ trackDefNode ( nd , DataFlow:: TypeBackTracker:: end ( ) , target )
14811486 }
14821487
14831488 /**
14841489 * Gets a node reached by the backwards tracking of `nd` in some state (e.g. possibly inside a content at this point).
14851490 */
1486- DataFlow:: SourceNode trackDefNodeAnyState ( DataFlow:: Node nd ) { result = trackDefNode ( nd , _) }
1491+ predicate trackDefNodeAnyState ( DataFlow:: Node nd , DataFlow:: SourceNode target ) {
1492+ trackDefNode ( nd , _, target )
1493+ }
14871494
14881495 private DataFlow:: SourceNode awaited ( DataFlow:: InvokeNode call , DataFlow:: TypeTracker t ) {
14891496 t .startInPromise ( ) and
@@ -1539,10 +1546,11 @@ module API {
15391546 )
15401547 )
15411548 or
1542- exists ( DataFlow:: Node def |
1549+ exists ( DataFlow:: Node def , DataFlow :: Node mid |
15431550 rhs ( pred , def ) and
15441551 lbl = Label:: instance ( ) and
1545- succ = MkClassInstance ( trackDefNode ( def ) )
1552+ trackDefNode ( def , mid ) and
1553+ succ = MkClassInstance ( mid )
15461554 )
15471555 or
15481556 exists ( string moduleName , string exportName |
@@ -1554,26 +1562,28 @@ module API {
15541562 exists ( DataFlow:: Node nd , DataFlow:: FunctionNode f |
15551563 f .getFunction ( ) .isAsync ( ) and
15561564 pred = MkDef ( nd ) and
1557- f = trackDefNode ( nd ) and
1565+ trackDefNode ( nd , f ) and
15581566 lbl = Label:: return ( ) and
15591567 succ = MkDef ( f .getReturnNode ( ) )
15601568 )
15611569 or
15621570 exists ( int bound , DataFlow:: InvokeNode call |
15631571 lbl = Label:: parameter ( bound + call .getNumArgument ( ) ) and
1564- call = getAPromisifiedInvocation ( pred , bound , succ )
1572+ getAPromisifiedInvocation ( pred , bound , succ , call )
15651573 )
15661574 }
15671575
15681576 /**
15691577 * Gets a call to a promisified function represented by `callee` where
15701578 * `bound` arguments have been bound.
15711579 */
1572- DataFlow:: InvokeNode getAPromisifiedInvocation ( TApiNode callee , int bound , TApiNode succ ) {
1580+ predicate getAPromisifiedInvocation (
1581+ TApiNode callee , int bound , TApiNode succ , DataFlow:: InvokeNode invoke
1582+ ) {
15731583 exists ( DataFlow:: SourceNode src |
15741584 use ( callee , src ) and
1575- trackUseNode ( src , true , bound , "" ) .flowsTo ( result .getCalleeNode ( ) ) and
1576- succ = Impl:: MkSyntheticCallbackArg ( result )
1585+ trackUseNode ( src , true , bound , "" ) .flowsTo ( invoke .getCalleeNode ( ) ) and
1586+ succ = Impl:: MkSyntheticCallbackArg ( invoke )
15771587 )
15781588 }
15791589 }
@@ -1606,23 +1616,24 @@ module API {
16061616
16071617 predicate rhs ( TApiNode node , DataFlow:: Node def ) = forceLocal( Stage1:: rhs / 2 ) ( node , def )
16081618
1609- DataFlow:: SourceNode trackUseNode ( DataFlow:: SourceNode nd ) =
1610- forceLocal( Stage1:: trackUseNode / 1 ) ( nd , result )
1619+ predicate trackUseNode ( DataFlow:: SourceNode nd , DataFlow:: SourceNode target ) =
1620+ forceLocal( Stage1:: trackUseNode / 2 ) ( nd , target )
16111621
1612- DataFlow:: SourceNode trackUseNodeAnyState ( DataFlow:: SourceNode nd ) =
1613- forceLocal( Stage1:: trackUseNodeAnyState / 1 ) ( nd , result )
1622+ predicate trackUseNodeAnyState ( DataFlow:: SourceNode nd , DataFlow:: SourceNode target ) =
1623+ forceLocal( Stage1:: trackUseNodeAnyState / 2 ) ( nd , target )
16141624
1615- DataFlow :: SourceNode trackDefNode ( DataFlow:: Node nd ) =
1616- forceLocal( Stage1:: trackDefNode / 1 ) ( nd , result )
1625+ predicate trackDefNode ( DataFlow:: Node nd , DataFlow :: SourceNode target ) =
1626+ forceLocal( Stage1:: trackDefNode / 2 ) ( nd , target )
16171627
1618- DataFlow :: SourceNode trackDefNodeAnyState ( DataFlow:: Node nd ) =
1619- forceLocal( Stage1:: trackDefNodeAnyState / 1 ) ( nd , result )
1628+ predicate trackDefNodeAnyState ( DataFlow:: Node nd , DataFlow :: SourceNode target ) =
1629+ forceLocal( Stage1:: trackDefNodeAnyState / 2 ) ( nd , target )
16201630
16211631 predicate edge ( TApiNode pred , Label:: ApiLabel lbl , TApiNode succ ) =
16221632 forceLocal( Stage1:: edge / 3 ) ( pred , lbl , succ )
16231633
1624- DataFlow:: InvokeNode getAPromisifiedInvocation ( TApiNode callee , int bound , TApiNode succ ) =
1625- forceLocal( Stage1:: getAPromisifiedInvocation / 3 ) ( callee , bound , succ , result )
1634+ predicate getAPromisifiedInvocation (
1635+ TApiNode callee , int bound , TApiNode succ , DataFlow:: InvokeNode invoke
1636+ ) = forceLocal( Stage1:: getAPromisifiedInvocation / 4 ) ( callee , bound , succ , invoke )
16261637 }
16271638
16281639 private module Stage2Input implements StageInputSig {
@@ -1651,8 +1662,9 @@ module API {
16511662 /** Holds if use-node tracking starting at `nd` can reach a node in the overlay. */
16521663 pragma [ nomagic]
16531664 private predicate shouldTrackIntoOverlay ( DataFlow:: SourceNode nd ) {
1654- exists ( DataFlow:: Node overlayNode |
1655- stepIntoOverlay ( Stage1Local:: trackUseNodeAnyState ( nd ) , overlayNode )
1665+ exists ( DataFlow:: Node mid |
1666+ Stage1Local:: trackUseNodeAnyState ( nd , mid ) and
1667+ stepIntoOverlay ( mid , _)
16561668 )
16571669 }
16581670
@@ -1677,8 +1689,9 @@ module API {
16771689 /** Holds if def-node tracking starting at `nd` can reach a node in the overlay. */
16781690 pragma [ nomagic]
16791691 private predicate shouldBacktrackIntoOverlay ( DataFlow:: Node nd ) {
1680- exists ( DataFlow:: Node overlayNode |
1681- stepOutOfOverlay ( overlayNode , Stage1Local:: trackDefNodeAnyState ( nd ) )
1692+ exists ( DataFlow:: Node mid |
1693+ Stage1Local:: trackDefNodeAnyState ( nd , mid ) and
1694+ stepOutOfOverlay ( _, mid )
16821695 )
16831696 }
16841697
@@ -1714,17 +1727,17 @@ module API {
17141727 }
17151728
17161729 cached
1717- DataFlow:: SourceNode trackUseNode ( DataFlow:: SourceNode nd ) {
1718- result = Stage1Local:: trackUseNode ( nd )
1730+ predicate trackUseNode ( DataFlow:: SourceNode nd , DataFlow:: SourceNode target ) {
1731+ Stage1Local:: trackUseNode ( nd , target )
17191732 or
1720- result = Stage2:: trackUseNode ( nd )
1733+ Stage2:: trackUseNode ( nd , target )
17211734 }
17221735
17231736 cached
1724- DataFlow :: SourceNode trackDefNode ( DataFlow:: Node nd ) {
1725- result = Stage1Local:: trackDefNode ( nd )
1737+ predicate trackDefNode ( DataFlow:: Node nd , DataFlow :: SourceNode target ) {
1738+ Stage1Local:: trackDefNode ( nd , target )
17261739 or
1727- result = Stage2:: trackDefNode ( nd )
1740+ Stage2:: trackDefNode ( nd , target )
17281741 }
17291742
17301743 cached
@@ -1735,10 +1748,12 @@ module API {
17351748 }
17361749
17371750 cached
1738- DataFlow:: InvokeNode getAPromisifiedInvocation ( TApiNode callee , int bound , TApiNode succ ) {
1739- result = Stage1Local:: getAPromisifiedInvocation ( callee , bound , succ )
1751+ predicate getAPromisifiedInvocation (
1752+ TApiNode callee , int bound , TApiNode succ , DataFlow:: InvokeNode invoke
1753+ ) {
1754+ Stage1Local:: getAPromisifiedInvocation ( callee , bound , succ , invoke )
17401755 or
1741- result = Stage2:: getAPromisifiedInvocation ( callee , bound , succ )
1756+ Stage2:: getAPromisifiedInvocation ( callee , bound , succ , invoke )
17421757 }
17431758 }
17441759
@@ -1808,7 +1823,7 @@ module API {
18081823 InvokeNode ( ) {
18091824 this = callee .getReturn ( ) .asSource ( ) or
18101825 this = callee .getInstance ( ) .asSource ( ) or
1811- this = Impl:: getAPromisifiedInvocation ( callee , _, _)
1826+ Impl:: getAPromisifiedInvocation ( callee , _, _, this )
18121827 }
18131828
18141829 /** Gets the API node for the `i`th parameter of this invocation. */
0 commit comments