Skip to content

Commit acf95d6

Browse files
committed
JS: Move summary resolution into JS-specific code
1 parent ab1642d commit acf95d6

File tree

3 files changed

+53
-53
lines changed

3 files changed

+53
-53
lines changed

javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource {
4040
*/
4141
private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) {
4242
exists(API::Node predNode, API::Node succNode |
43-
ModelOutput::summaryStep(predNode, succNode, kind) and
43+
Specific::summaryStep(predNode, succNode, kind) and
4444
pred = predNode.getARhs() and
4545
succ = succNode.getAnImmediateUse()
4646
)

javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ private class AccessPathRange extends AccessPath::Range {
268268
* Gets a successor of `node` in the API graph.
269269
*/
270270
bindingset[token]
271-
private API::Node getSuccessorFromNode(API::Node node, AccessPathToken token) {
271+
API::Node getSuccessorFromNode(API::Node node, AccessPathToken token) {
272272
// API graphs use the same label for arguments and parameters. An edge originating from a
273273
// use-node represents be an argument, and an edge originating from a def-node represents a parameter.
274274
// We just map both to the same thing.
@@ -289,7 +289,7 @@ private API::Node getSuccessorFromNode(API::Node node, AccessPathToken token) {
289289
* Gets an API-graph successor for the given invocation.
290290
*/
291291
bindingset[token]
292-
private API::Node getSuccessorFromInvoke(API::InvokeNode invoke, AccessPathToken token) {
292+
API::Node getSuccessorFromInvoke(API::InvokeNode invoke, AccessPathToken token) {
293293
token.getName() = "Argument" and
294294
(
295295
result = invoke.getParameter(getAnIntFromStringUnbounded(token.getAnArgument()))
@@ -367,50 +367,6 @@ API::InvokeNode getInvocationFromPath(string package, string type, AccessPath pa
367367
result = getInvocationFromPath(package, type, path, path.getNumToken())
368368
}
369369

370-
/**
371-
* Holds if a summary edge with the given `input, output, kind` columns have a `package, type, path` tuple
372-
* that resolves to `baseNode`.
373-
*/
374-
private predicate resolvedSummaryBase(
375-
API::InvokeNode baseNode, AccessPath input, AccessPath output, string kind
376-
) {
377-
exists(string package, string type, AccessPath path |
378-
summaryModel(package, type, path, input, output, kind) and
379-
baseNode = getInvocationFromPath(package, type, path)
380-
)
381-
}
382-
383-
/**
384-
* Holds if `path` is an input or output spec for a summary with the given `base` node.
385-
*/
386-
pragma[nomagic]
387-
private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath path) {
388-
resolvedSummaryBase(base, path, _, _)
389-
or
390-
resolvedSummaryBase(base, _, path, _)
391-
}
392-
393-
/**
394-
* Gets the API node for the first `n` tokens of the given input/output path, evaluated relative to `baseNode`.
395-
*/
396-
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path, int n) {
397-
relevantInputOutputPath(baseNode, path) and
398-
(
399-
n = 1 and
400-
result = getSuccessorFromInvoke(baseNode, path.getToken(0))
401-
or
402-
result =
403-
getSuccessorFromNode(getNodeFromInputOutputPath(baseNode, path, n - 1), path.getToken(n - 1))
404-
)
405-
}
406-
407-
/**
408-
* Gets the API node for the given input/output path, evaluated relative to `baseNode`.
409-
*/
410-
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path) {
411-
result = getNodeFromInputOutputPath(baseNode, path, path.getNumToken())
412-
}
413-
414370
/**
415371
* Convenience-predicate for extracting two capture groups at once.
416372
*/
@@ -519,13 +475,15 @@ module ModelOutput {
519475
}
520476

521477
/**
522-
* Holds if a CSV summary contributed the step `pred -> succ` of the given `kind`.
478+
* Holds if a summary edge with the given `input, output, kind` columns have a `package, type, path` tuple
479+
* that resolves to `baseNode`.
523480
*/
524-
predicate summaryStep(API::Node pred, API::Node succ, string kind) {
525-
exists(API::InvokeNode base, AccessPath input, AccessPath output |
526-
resolvedSummaryBase(base, input, output, kind) and
527-
pred = getNodeFromInputOutputPath(base, input) and
528-
succ = getNodeFromInputOutputPath(base, output)
481+
predicate resolvedSummaryBase(
482+
API::InvokeNode baseNode, AccessPath input, AccessPath output, string kind
483+
) {
484+
exists(string package, string type, AccessPath path |
485+
summaryModel(package, type, path, input, output, kind) and
486+
baseNode = getInvocationFromPath(package, type, path)
529487
)
530488
}
531489

javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,45 @@ predicate invocationMatchesExtraCallSiteFilter(API::InvokeNode invoke, AccessPat
132132
invoke instanceof API::CallNode and
133133
invoke instanceof DataFlow::CallNode // Workaround compiler bug
134134
}
135+
136+
/**
137+
* Holds if `path` is an input or output spec for a summary with the given `base` node.
138+
*/
139+
pragma[nomagic]
140+
private predicate relevantInputOutputPath(API::InvokeNode base, AccessPath path) {
141+
ModelOutput::resolvedSummaryBase(base, path, _, _)
142+
or
143+
ModelOutput::resolvedSummaryBase(base, _, path, _)
144+
}
145+
146+
/**
147+
* Gets the API node for the first `n` tokens of the given input/output path, evaluated relative to `baseNode`.
148+
*/
149+
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path, int n) {
150+
relevantInputOutputPath(baseNode, path) and
151+
(
152+
n = 1 and
153+
result = getSuccessorFromInvoke(baseNode, path.getToken(0))
154+
or
155+
result =
156+
getSuccessorFromNode(getNodeFromInputOutputPath(baseNode, path, n - 1), path.getToken(n - 1))
157+
)
158+
}
159+
160+
/**
161+
* Gets the API node for the given input/output path, evaluated relative to `baseNode`.
162+
*/
163+
private API::Node getNodeFromInputOutputPath(API::InvokeNode baseNode, AccessPath path) {
164+
result = getNodeFromInputOutputPath(baseNode, path, path.getNumToken())
165+
}
166+
167+
/**
168+
* Holds if a CSV summary contributed the step `pred -> succ` of the given `kind`.
169+
*/
170+
predicate summaryStep(API::Node pred, API::Node succ, string kind) {
171+
exists(API::InvokeNode base, AccessPath input, AccessPath output |
172+
ModelOutput::resolvedSummaryBase(base, input, output, kind) and
173+
pred = getNodeFromInputOutputPath(base, input) and
174+
succ = getNodeFromInputOutputPath(base, output)
175+
)
176+
}

0 commit comments

Comments
 (0)