Skip to content

Commit db1de18

Browse files
committed
JS: Support transitive callback-passing
1 parent ceaf2b3 commit db1de18

File tree

4 files changed

+18
-4
lines changed

4 files changed

+18
-4
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,18 @@ private module CachedSteps {
450450
)
451451
}
452452

453+
/** Gets a function that flows to `parameter` via one or more parameter-passing steps. */
454+
cached
455+
DataFlow::FunctionNode getACallbackSource(DataFlow::ParameterNode parameter) {
456+
Stages::TypeTracking::ref() and
457+
callStep(result.getALocalUse(), parameter)
458+
or
459+
exists(DataFlow::ParameterNode mid |
460+
callStep(mid.getALocalUse(), parameter) and
461+
result = getACallbackSource(mid)
462+
)
463+
}
464+
453465
/**
454466
* Holds if `f` may return `base`, which has a write of property `prop` with right-hand side `rhs`.
455467
*/

javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,9 @@ private module Cached {
158158
)
159159
or
160160
// Add 'return' steps from callback arguments to callback parameters
161-
exists(DataFlow::ParameterNode cbParam, DataFlow::FunctionNode cbFun, int i |
162-
callStep(cbFun, cbParam) and
163-
pred = cbParam.getAnInvocation().getArgument(i) and
164-
succ = cbFun.getParameter(i) and
161+
exists(DataFlow::ParameterNode parameter, int i |
162+
pred = parameter.getAnInvocation().getArgument(i) and
163+
succ = getACallbackSource(parameter).getParameter(i) and
165164
summary = ReturnStep()
166165
)
167166
}

javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ test_Connection
3939
| tst.js:114:1:114:28 | getX({ ... on() }) |
4040
| tst.js:114:11:114:25 | getConnection() |
4141
| tst.js:118:12:118:26 | getConnection() |
42+
| tst.js:120:21:120:24 | conn |
43+
| tst.js:126:22:126:25 | conn |
4244
| tst_conflict.js:6:38:6:77 | api.cha ... ction() |
4345
test_DataCallback
4446
| client.js:3:28:3:34 | x => {} |

javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ connection
4242
| type tracker without call steps | tst.js:114:11:114:25 | getConnection() |
4343
| type tracker without call steps | tst.js:118:12:118:26 | getConnection() |
4444
| type tracker without call steps | tst.js:120:21:120:24 | conn |
45+
| type tracker without call steps | tst.js:126:22:126:25 | conn |
4546
| type tracker without call steps | tst_conflict.js:6:38:6:77 | api.cha ... ction() |
4647
| type tracker without call steps with property MyApplication.namespace.connection | file://:0:0:0:0 | global access path |
4748
| type tracker without call steps with property conflict | tst.js:63:3:63:25 | MyAppli ... mespace |

0 commit comments

Comments
 (0)