@@ -121,16 +121,9 @@ class AggregateES2015PromiseDefinition extends PromiseCreationCall {
121121}
122122
123123/**
124- * This module defines how data-flow propagates into and out a Promise.
124+ * This module defines how exceptional data-flow propagates into and out a Promise.
125125 */
126- private module PromiseFlow {
127- /**
128- * Gets the pseudo-field used to describe resolved values in a promise.
129- */
130- string resolveField ( ) {
131- result = "$PromiseResolveField$"
132- }
133-
126+ private module ExceptionalPromiseFlow {
134127 /**
135128 * Gets the pseudo-field used to describe rejected values in a promise.
136129 */
@@ -141,7 +134,7 @@ private module PromiseFlow {
141134 /**
142135 * A flow step describing a promise definition.
143136 *
144- * The resolved/ rejected value is written to a pseudo-field on the promise.
137+ * The rejected value is written to a pseudo-field on the promise.
145138 */
146139 class PromiseDefitionStep extends DataFlow:: AdditionalFlowStep {
147140 PromiseDefinition promise ;
@@ -150,10 +143,6 @@ private module PromiseFlow {
150143 }
151144
152145 override predicate store ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
153- prop = resolveField ( ) and
154- pred = promise .getResolveParameter ( ) .getACall ( ) .getArgument ( 0 ) and
155- succ = this
156- or
157146 prop = rejectField ( ) and
158147 (
159148 pred = promise .getRejectParameter ( ) .getACall ( ) .getArgument ( 0 ) or
@@ -164,25 +153,8 @@ private module PromiseFlow {
164153 }
165154
166155 /**
167- * A flow step describing the a Promise.resolve (and similar) call.
168- */
169- class CreationStep extends DataFlow:: AdditionalFlowStep {
170- PromiseCreationCall promise ;
171- CreationStep ( ) {
172- this = promise
173- }
174-
175- override predicate store ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
176- prop = resolveField ( ) and
177- pred = promise .getValue ( ) and
178- succ = this
179- }
180- }
181-
182- /**
183- * A load step loading the pseudo-field describing that the promise is either resolved or rejected.
184- * A resolved value is forwarding as the resulting value of the `await` expression,
185- * and a rejected value is thrown as a exception.
156+ * A load step loading the pseudo-field describing that the promise is rejected.
157+ * The rejected value is thrown as a exception.
186158 */
187159 class AwaitStep extends DataFlow:: AdditionalFlowStep {
188160 DataFlow:: Node operand ;
@@ -193,10 +165,6 @@ private module PromiseFlow {
193165 }
194166
195167 override predicate load ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
196- prop = resolveField ( ) and
197- succ = this and
198- pred = operand .getALocalSource ( )
199- or
200168 prop = rejectField ( ) and
201169 succ = await .getExceptionTarget ( ) and
202170 pred = operand .getALocalSource ( )
@@ -212,10 +180,6 @@ private module PromiseFlow {
212180 }
213181
214182 override predicate load ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
215- prop = resolveField ( ) and
216- pred = getReceiver ( ) .getALocalSource ( ) and
217- succ = getCallback ( 0 ) .getParameter ( 0 )
218- or
219183 prop = rejectField ( ) and
220184 pred = getReceiver ( ) .getALocalSource ( ) and
221185 succ = getCallback ( 1 ) .getParameter ( 0 )
@@ -229,10 +193,6 @@ private module PromiseFlow {
229193 }
230194
231195 override predicate store ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
232- prop = resolveField ( ) and
233- pred = getCallback ( [ 0 ..1 ] ) .getAReturn ( ) and
234- succ = this
235- or
236196 prop = rejectField ( ) and
237197 pred = getCallback ( [ 0 ..1 ] ) .getExceptionalReturn ( ) and
238198 succ = this
@@ -253,12 +213,6 @@ private module PromiseFlow {
253213 succ = getCallback ( 0 ) .getParameter ( 0 )
254214 }
255215
256- override predicate copyProperty ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
257- prop = resolveField ( ) and
258- pred = getReceiver ( ) .getALocalSource ( ) and
259- succ = this
260- }
261-
262216 override predicate store ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
263217 prop = rejectField ( ) and
264218 pred = getCallback ( [ 0 ..1 ] ) .getExceptionalReturn ( ) and
@@ -275,7 +229,7 @@ private module PromiseFlow {
275229 }
276230
277231 override predicate copyProperty ( DataFlow:: Node pred , DataFlow:: Node succ , string prop ) {
278- ( prop = resolveField ( ) or prop = rejectField ( ) ) and
232+ prop = rejectField ( ) and
279233 pred = getReceiver ( ) .getALocalSource ( ) and
280234 succ = this
281235 }
@@ -292,17 +246,35 @@ predicate promiseTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
292246 // from `x` to `Promise.resolve(x)`
293247 pred = succ .( PromiseCreationCall ) .getValue ( )
294248 or
295- exists ( DataFlow:: MethodCallNode thn , DataFlow :: FunctionNode cb |
296- thn .getMethodName ( ) = "then" and cb = thn . getCallback ( 0 )
249+ exists ( DataFlow:: MethodCallNode thn |
250+ thn .getMethodName ( ) = "then"
297251 |
298252 // from `p` to `x` in `p.then(x => ...)`
299253 pred = thn .getReceiver ( ) and
300- succ = cb .getParameter ( 0 )
254+ succ = thn . getCallback ( 0 ) .getParameter ( 0 )
301255 or
302256 // from `v` to `p.then(x => return v)`
303- pred = cb .getAReturn ( ) and
257+ pred = thn . getCallback ( [ 0 .. 1 ] ) .getAReturn ( ) and
304258 succ = thn
305259 )
260+ or
261+ // from `p` to `p.catch(..)`
262+ exists ( DataFlow:: MethodCallNode catch | catch .getMethodName ( ) = "catch" |
263+ pred = catch .getReceiver ( ) and
264+ succ = catch
265+ )
266+ or
267+ // from `p` to `p.finally(..)`
268+ exists ( DataFlow:: MethodCallNode finally | finally .getMethodName ( ) = "finally" |
269+ pred = finally .getReceiver ( ) and
270+ succ = finally
271+ )
272+ or
273+ // from `x` to `await x`
274+ exists ( AwaitExpr await |
275+ pred .getEnclosingExpr ( ) = await .getOperand ( ) and
276+ succ .getEnclosingExpr ( ) = await
277+ )
306278}
307279
308280/**
0 commit comments