Skip to content

Commit 22b56a4

Browse files
committed
JS: More implied receiver steps
1 parent f2939bd commit 22b56a4

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,20 @@ module CallGraph {
279279
StepSummary::step(getAnAllocationSiteRef(node), result, objectWithMethodsStep())
280280
}
281281

282+
/**
283+
* Holds if `function` flows to a property of `host` via non-local data flow.
284+
*/
285+
pragma[nomagic]
286+
private predicate complexMethodInstallation(
287+
DataFlow::SourceNode host, DataFlow::FunctionNode function
288+
) {
289+
not function = getAMethodOnObject(_) and
290+
exists(DataFlow::TypeTracker t |
291+
getAFunctionReference(function, 0, t) = host.getAPropertySource() and
292+
t.start() // require call bit to be false
293+
)
294+
}
295+
282296
/**
283297
* Holds if `pred` is assumed to flow to `succ` because a method is stored on an object that is assumed
284298
* to be the receiver of calls to that method.
@@ -291,9 +305,18 @@ module CallGraph {
291305
*/
292306
cached
293307
predicate impliedReceiverStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
308+
// To avoid double-recursion, we handle either complex flow for the host object, or for the function, but not both.
294309
exists(DataFlow::SourceNode host |
310+
// Complex flow for the host object
295311
pred = getAnAllocationSiteRef(host) and
296312
succ = getAMethodOnObject(host).getReceiver()
313+
or
314+
// Complex flow for the function
315+
exists(DataFlow::FunctionNode function |
316+
complexMethodInstallation(host, function) and
317+
pred = host and
318+
succ = function.getReceiver()
319+
)
297320
)
298321
}
299322
}

javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/Test.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ spuriousCallee
22
missingCallee
33
| constructor-field.ts:40:5:40:14 | f3.build() | constructor-field.ts:13:3:13:12 | build() {} | -1 | calls |
44
| constructor-field.ts:71:1:71:11 | bf3.build() | constructor-field.ts:13:3:13:12 | build() {} | -1 | calls |
5-
| implied-receiver.js:7:13:7:25 | this.member() | implied-receiver.js:17:22:19:1 | functio ... n 42;\\n} | -1 | calls |
65
badAnnotation
76
accessorCall
87
| accessors.js:12:1:12:5 | obj.f | accessors.js:5:8:5:12 | () {} |

0 commit comments

Comments
 (0)