Skip to content

Commit f81860c

Browse files
authored
Merge pull request github#5200 from erik-krogh/apiJoin
Approved by max-schaefer
2 parents 3062f41 + 6f38463 commit f81860c

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

javascript/ql/src/semmle/javascript/ApiGraphs.qll

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -738,25 +738,27 @@ module API {
738738
boundArgs in [0 .. 10]
739739
)
740740
or
741-
exists(StepSummary summary |
742-
t = useStep(nd, promisified, boundArgs, result, summary).append(summary)
743-
)
741+
t = useStep(nd, promisified, boundArgs, result)
744742
}
745743

746744
private import semmle.javascript.dataflow.internal.StepSummary
747745

748746
/**
749747
* Holds if `nd`, which is a use of an API-graph node, flows in zero or more potentially
750748
* inter-procedural steps to some intermediate node, and then from that intermediate node to
751-
* `res` in one step described by `summary`.
749+
* `res` in one step. The entire flow is described by the resulting `TypeTracker`.
752750
*
753751
* This predicate exists solely to enforce a better join order in `trackUseNode` above.
754752
*/
755-
pragma[noinline]
753+
pragma[noopt]
756754
private DataFlow::TypeTracker useStep(
757-
DataFlow::Node nd, boolean promisified, int boundArgs, DataFlow::Node res, StepSummary summary
755+
DataFlow::Node nd, boolean promisified, int boundArgs, DataFlow::Node res
758756
) {
759-
StepSummary::step(trackUseNode(nd, promisified, boundArgs, result), res, summary)
757+
exists(DataFlow::TypeTracker t, StepSummary summary, DataFlow::SourceNode prev |
758+
prev = trackUseNode(nd, promisified, boundArgs, t) and
759+
StepSummary::step(prev, res, summary) and
760+
result = t.append(summary)
761+
)
760762
}
761763

762764
private DataFlow::SourceNode trackUseNode(
@@ -788,7 +790,23 @@ module API {
788790
)
789791
)
790792
or
791-
exists(DataFlow::TypeBackTracker t2 | result = trackDefNode(nd, t2).backtrack(t2, t))
793+
t = defStep(nd, result)
794+
}
795+
796+
/**
797+
* Holds if `nd`, which is a def of an API-graph node, can be reached in zero or more potentially
798+
* inter-procedural steps from some intermediate node, and `prev` flows into that intermediate node
799+
* in one step. The entire flow is described by the resulting `TypeTracker`.
800+
*
801+
* This predicate exists solely to enforce a better join order in `trackDefNode` above.
802+
*/
803+
pragma[noopt]
804+
private DataFlow::TypeBackTracker defStep(DataFlow::Node nd, DataFlow::SourceNode prev) {
805+
exists(DataFlow::TypeBackTracker t, StepSummary summary, DataFlow::Node next |
806+
next = trackDefNode(nd, t) and
807+
StepSummary::step(prev, next, summary) and
808+
result = t.prepend(summary)
809+
)
792810
}
793811

794812
/**
@@ -912,11 +930,17 @@ module API {
912930
}
913931

914932
/** Gets the API node for the `i`th parameter of this invocation. */
933+
pragma[nomagic]
915934
Node getParameter(int i) {
916935
result = callee.getParameter(i) and
917-
result.getARhs() = getArgument(i)
936+
result = getAParameterCandidate(i)
918937
}
919938

939+
/**
940+
* Gets an API node where a RHS of the node is the `i`th argument to this call.
941+
*/
942+
private Node getAParameterCandidate(int i) { result.getARhs() = getArgument(i) }
943+
920944
/** Gets the API node for a parameter of this invocation. */
921945
Node getAParameter() { result = getParameter(_) }
922946

0 commit comments

Comments
 (0)