mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
JS: recognize A.substr(0, B.length) == B
This commit is contained in:
@@ -147,6 +147,37 @@ module StringOps {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison of form `x.substring(0, y.length) === y`.
|
||||
*/
|
||||
private class StartsWith_Substring extends StartsWith, DataFlow::ValueNode {
|
||||
override EqualityTest astNode;
|
||||
DataFlow::MethodCallNode call;
|
||||
DataFlow::Node substring;
|
||||
|
||||
StartsWith_Substring() {
|
||||
astNode.hasOperands(call.asExpr(), substring.asExpr()) and
|
||||
(call.getMethodName() = "substring" or call.getMethodName() = "substr") and
|
||||
call.getNumArgument() = 2 and
|
||||
(
|
||||
substring.getALocalSource().getAPropertyRead("length").flowsTo(call.getArgument(1))
|
||||
or
|
||||
substring.asExpr().getStringValue().length() = call.getArgument(1).asExpr().getIntValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getBaseString() {
|
||||
result = call.getReceiver()
|
||||
}
|
||||
|
||||
override DataFlow::Node getSubstring() {
|
||||
result = substring
|
||||
}
|
||||
|
||||
override boolean getPolarity() {
|
||||
result = astNode.getPolarity()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A expression that is equivalent to `A.includes(B)` or `!A.includes(B)`.
|
||||
|
||||
@@ -8,3 +8,7 @@
|
||||
| tst.js:12:9:12:20 | A.indexOf(B) | tst.js:12:9:12:9 | A | tst.js:12:19:12:19 | B | false |
|
||||
| tst.js:13:10:13:21 | A.indexOf(B) | tst.js:13:10:13:10 | A | tst.js:13:20:13:20 | B | false |
|
||||
| tst.js:14:11:14:22 | A.indexOf(B) | tst.js:14:11:14:11 | A | tst.js:14:21:14:21 | B | false |
|
||||
| tst.js:15:9:15:38 | A.subst ... ) === B | tst.js:15:9:15:9 | A | tst.js:15:38:15:38 | B | true |
|
||||
| tst.js:16:9:16:38 | A.subst ... ) !== B | tst.js:16:9:16:9 | A | tst.js:16:38:16:38 | B | false |
|
||||
| tst.js:17:9:17:35 | A.subst ... ) === B | tst.js:17:9:17:9 | A | tst.js:17:35:17:35 | B | true |
|
||||
| tst.js:18:9:18:36 | A.subst ... "web/" | tst.js:18:9:18:9 | A | tst.js:18:31:18:36 | "web/" | true |
|
||||
|
||||
@@ -12,6 +12,10 @@ function f(A, B) {
|
||||
if (A.indexOf(B)) {} // !startsWith
|
||||
if (!A.indexOf(B)) {} // startsWith
|
||||
if (!!A.indexOf(B)) {} // !startsWith
|
||||
if (A.substring(0, B.length) === B) {}
|
||||
if (A.substring(0, B.length) !== B) {}
|
||||
if (A.substr(0, B.length) === B) {}
|
||||
if (A.substring(0, 4) === "web/") {}
|
||||
|
||||
// non-examples
|
||||
if (_.startsWith(A, B, 2)) {}
|
||||
@@ -22,4 +26,5 @@ function f(A, B) {
|
||||
if (A.indexOf(B, 2) === 0) {}
|
||||
if (A.indexOf(B, 2)) {}
|
||||
if (~A.indexOf(B)) {} // checks for existence, not startsWith
|
||||
if (A.substring(B.length) === 0) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user