@@ -85,7 +85,7 @@ private class ES2015PromiseDefinition extends PromiseDefinition, DataFlow::NewNo
8585 */
8686abstract class PromiseCreationCall extends DataFlow:: CallNode {
8787 /**
88- * Gets the value this promise is resolved with.
88+ * Gets a value this promise is resolved with.
8989 */
9090 abstract DataFlow:: Node getValue ( ) ;
9191}
@@ -95,6 +95,16 @@ abstract class PromiseCreationCall extends DataFlow::CallNode {
9595 */
9696abstract class ResolvedPromiseDefinition extends PromiseCreationCall { }
9797
98+ /**
99+ * A promise that is created using a `Promise.all(array)` call.
100+ */
101+ abstract class PromiseAllCreation extends PromiseCreationCall {
102+ /**
103+ * Gets a node for the array of values given to the `Promise.all(array)` call.
104+ */
105+ abstract DataFlow:: Node getArrayNode ( ) ;
106+ }
107+
98108/**
99109 * A resolved promise created by the standard ECMAScript 2015 `Promise.resolve` function.
100110 */
@@ -121,6 +131,15 @@ class AggregateES2015PromiseDefinition extends PromiseCreationCall {
121131 }
122132}
123133
134+ /**
135+ * An aggregated promise created using `Promise.all()`.
136+ */
137+ class ES2015PromiseAllDefinition extends AggregateES2015PromiseDefinition , PromiseAllCreation {
138+ ES2015PromiseAllDefinition ( ) { this .getCalleeName ( ) = "all" }
139+
140+ override DataFlow:: Node getArrayNode ( ) { result = getArgument ( 0 ) }
141+ }
142+
124143/**
125144 * Common predicates shared between type-tracking and data-flow for promises.
126145 */
@@ -303,16 +322,27 @@ private module PromiseFlow {
303322 CreationStep ( ) { this = promise }
304323
305324 override predicate store ( DataFlow:: Node pred , DataFlow:: SourceNode succ , string prop ) {
325+ not promise instanceof PromiseAllCreation and
306326 prop = valueProp ( ) and
307327 pred = promise .getValue ( ) and
308328 succ = this
329+ or
330+ prop = valueProp ( ) and
331+ pred = promise .( PromiseAllCreation ) .getArrayNode ( ) and
332+ succ = this
309333 }
310334
311335 override predicate loadStore ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
312336 // Copy the value of a resolved promise to the value of this promise.
337+ not promise instanceof PromiseAllCreation and
313338 prop = valueProp ( ) and
314339 pred = promise .getValue ( ) and
315340 succ = this
341+ or
342+ promise instanceof PromiseAllCreation and
343+ prop = valueProp ( ) and
344+ pred = promise .( PromiseAllCreation ) .getArrayNode ( ) and
345+ succ = this
316346 }
317347 }
318348
@@ -446,7 +476,11 @@ predicate promiseTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
446476 pred = succ .( PromiseDefinition ) .getResolveParameter ( ) .getACall ( ) .getArgument ( 0 )
447477 or
448478 // from `x` to `Promise.resolve(x)`
449- pred = succ .( PromiseCreationCall ) .getValue ( )
479+ pred = succ .( PromiseCreationCall ) .getValue ( ) and
480+ not succ instanceof PromiseAllCreation
481+ or
482+ // from `arr` to `Promise.all(arr)`
483+ pred = succ .( PromiseAllCreation ) .getArrayNode ( )
450484 or
451485 exists ( DataFlow:: MethodCallNode thn | thn .getMethodName ( ) = "then" |
452486 // from `p` to `x` in `p.then(x => ...)`
@@ -533,6 +567,15 @@ module Bluebird {
533567 result = getArgument ( 0 ) .getALocalSource ( ) .( DataFlow:: ArrayCreationNode ) .getAnElement ( )
534568 }
535569 }
570+
571+ /**
572+ * A promise created using `Promise.all`:
573+ */
574+ class BluebirdPromiseAllDefinition extends AggregateBluebirdPromiseDefinition , PromiseAllCreation {
575+ BluebirdPromiseAllDefinition ( ) { this .getCalleeName ( ) = "all" }
576+
577+ override DataFlow:: Node getArrayNode ( ) { result = getArgument ( 0 ) }
578+ }
536579}
537580
538581/**
0 commit comments