Skip to content

Commit 54fd7d9

Browse files
committed
share implementation instead of copy-pasting
1 parent 94cf3a8 commit 54fd7d9

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

javascript/ql/src/semmle/javascript/Promises.qll

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -477,17 +477,8 @@ private module AsyncReturnSteps {
477477
succ = f.getReturnNode()
478478
or
479479
// exceptional return
480-
// Note: partially copy-paste from FlowSteps::localExceptionStep/2
481480
prop = errorProp() and
482-
exists(Expr expr |
483-
expr = any(ThrowStmt throw).getExpr() and
484-
pred = expr.flow()
485-
or
486-
DataFlow::exceptionalInvocationReturnNode(pred, expr)
487-
|
488-
f.getFunction() = expr.getContainer() and
489-
succ = f.getReturnNode() // returns a rejected promise - therefore using the ordinary return node.
490-
)
481+
localExceptionStepWithAsyncFlag(pred, succ, true)
491482
)
492483
}
493484
}

javascript/ql/src/semmle/javascript/dataflow/internal/FlowSteps.qll

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,29 @@ predicate localFlowStep(
6161
* Holds if an exception thrown from `pred` can propagate locally to `succ`.
6262
*/
6363
predicate localExceptionStep(DataFlow::Node pred, DataFlow::Node succ) {
64-
// Note: FlowSteps::localExceptionStep/2 has copy-paste children
64+
localExceptionStepWithAsyncFlag(pred, succ, false)
65+
}
66+
67+
/**
68+
* Holds if an exception thrown from `pred` can propagate locally to `succ`.
69+
*
70+
* The `async` flag is true if the successor
71+
*/
72+
predicate localExceptionStepWithAsyncFlag(DataFlow::Node pred, DataFlow::Node succ, boolean async) {
6573
exists(Expr expr |
6674
expr = any(ThrowStmt throw).getExpr() and
6775
pred = expr.flow()
6876
or
6977
DataFlow::exceptionalInvocationReturnNode(pred, expr)
7078
|
79+
async = false and
7180
succ = expr.getExceptionTarget() and
7281
not succ = any(DataFlow::FunctionNode f | f.getFunction().isAsync()).getExceptionalReturn()
82+
or
83+
async = true and
84+
exists(DataFlow::FunctionNode f | f.getExceptionalReturn() = expr.getExceptionTarget() |
85+
succ = f.getReturnNode() // returns a rejected promise - therefore using the ordinary return node.
86+
)
7387
)
7488
}
7589

0 commit comments

Comments
 (0)