Skip to content

Commit d2d5af4

Browse files
committed
add IndirectInclusionTest and IndirectEndsWith
1 parent 97c1692 commit d2d5af4

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

javascript/ql/src/semmle/javascript/InclusionTests.qll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,40 @@ module InclusionTest {
5858
boolean getPolarity() { result = true }
5959
}
6060

61+
/**
62+
* A call to a utility function (`callee`) that performs an InclusionTest (`inner`).
63+
*/
64+
private class IndirectInclusionTest extends Range, DataFlow::CallNode {
65+
InclusionTest inner;
66+
Function callee;
67+
68+
IndirectInclusionTest() {
69+
inner.getEnclosingExpr() = callee.getAReturnedExpr() and
70+
this.getACallee() = callee and
71+
count(this.getACallee()) = 1 and
72+
count(callee.getAReturnedExpr()) = 1 and
73+
not this.isImprecise() and
74+
inner.getContainerNode().getALocalSource().getEnclosingExpr() = callee.getAParameter() and
75+
inner.getContainedNode().getALocalSource().getEnclosingExpr() = callee.getAParameter()
76+
}
77+
78+
override DataFlow::Node getContainerNode() {
79+
exists(int arg |
80+
inner.getContainerNode().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
81+
result = this.getArgument(arg)
82+
)
83+
}
84+
85+
override DataFlow::Node getContainedNode() {
86+
exists(int arg |
87+
inner.getContainedNode().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
88+
result = this.getArgument(arg)
89+
)
90+
}
91+
92+
override boolean getPolarity() { result = inner.getPolarity() }
93+
}
94+
6195
/**
6296
* A call to a method named `includes`, assumed to refer to `String.prototype.includes`
6397
* or `Array.prototype.includes`.

javascript/ql/src/semmle/javascript/StringOps.qll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,41 @@ module StringOps {
287287
boolean getPolarity() { result = true }
288288
}
289289

290+
/**
291+
* A call to a utility function (`callee`) that performs an EndsWith check (`inner`).
292+
*/
293+
private class IndirectEndsWith extends Range, DataFlow::CallNode {
294+
EndsWith inner;
295+
Function callee;
296+
297+
IndirectEndsWith() {
298+
inner.getEnclosingExpr() = callee.getAReturnedExpr() and
299+
this.getACallee() = callee and
300+
count(this.getACallee()) = 1 and
301+
count(callee.getAReturnedExpr()) = 1 and
302+
not this.isImprecise() and
303+
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getAParameter() and
304+
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getAParameter()
305+
}
306+
307+
override DataFlow::Node getBaseString() {
308+
exists(int arg |
309+
inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
310+
result = this.getArgument(arg)
311+
)
312+
}
313+
314+
override DataFlow::Node getSubstring() {
315+
exists(int arg |
316+
inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and
317+
result = this.getArgument(arg)
318+
)
319+
}
320+
321+
override boolean getPolarity() { result = inner.getPolarity() }
322+
}
323+
324+
290325
/**
291326
* A call of form `A.endsWith(B)`.
292327
*/

0 commit comments

Comments
 (0)