Merge pull request #2593 from asger-semmle/regexp-always-matches

JS: Add RegExpAlwaysMatches query
This commit is contained in:
Max Schaefer
2020-01-08 15:21:39 +00:00
committed by GitHub
11 changed files with 303 additions and 19 deletions

View File

@@ -0,0 +1,8 @@
| tst.js:2:11:2:20 | ^(https:)? | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:2:10:2:29 | /^(https:)?/.test(x) | here |
| tst.js:14:11:14:19 | (\\.com)?$ | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:14:10:14:28 | /(\\.com)?$/.test(x) | here |
| tst.js:22:11:22:34 | ^(?:https?:\|ftp:\|file:)? | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:22:10:22:43 | /^(?:ht ... test(x) | here |
| tst.js:30:11:30:20 | (foo\|bar)? | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:30:10:30:29 | /(foo\|bar)?/.test(x) | here |
| tst.js:34:21:34:26 | (baz)? | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:34:10:34:35 | /^foo\|b ... test(x) | here |
| tst.js:58:20:58:25 | [a-z]* | This regular expression always the matches at index 0 when used $@, as it matches the empty substring. | tst.js:58:10:58:27 | x.search(/[a-z]*/) | here |
| tst.js:70:20:70:26 | ^(foo)? | This regular expression always the matches at index 0 when used $@, as it matches the empty substring. | tst.js:70:10:70:28 | x.search(/^(foo)?/) | here |
| tst.js:86:22:86:21 | | This regular expression always matches when used in a test $@, as it can match an empty substring. | tst.js:86:10:86:31 | new Reg ... test(x) | here |

View File

@@ -0,0 +1 @@
RegExp/RegExpAlwaysMatches.ql

View File

@@ -0,0 +1,87 @@
function optionalPrefix(x) {
return /^(https:)?/.test(x); // NOT OK
}
function mandatoryPrefix(x) {
return /^https:/.test(x); // OK
}
function httpOrHttps(x) {
return /^https?:/.test(x); // OK
}
function optionalSuffix(x) {
return /(\.com)?$/.test(x); // NOT OK
}
function mandatorySuffix(x) {
return /\.com$/.test(x); // OK
}
function protocol(x) {
return /^(?:https?:|ftp:|file:)?/.test(x); // NOT OK
}
function doubleAnchored(x) {
return /^(foo|bar)?$/.test(x); // OK
}
function noAnchor(x) {
return /(foo|bar)?/.test(x); // NOT OK
}
function altAnchor(x) {
return /^foo|bar$|(baz)?/.test(x); // NOT OK
}
function wildcard(x) {
return /.*/.test(x); // OK - obviously intended to match anything
}
function wildcard2(x) {
return /[\d\D]*/.test(x); // OK - obviously intended to match anything
}
function emptyAlt(x) {
return /^$|foo|bar/.test(x); // OK
}
function emptyAlt2(x) {
return /(^$|foo|bar)/.test(x); // OK
}
function emptyAlt3(x) {
return /((^$|foo|bar))/.test(x); // OK
}
function search(x) {
return x.search(/[a-z]*/); // NOT OK
}
function search2(x) {
return x.search(/[a-z]/); // OK
}
function lookahead(x) {
return x.search(/(?!x)/); // OK
}
function searchPrefix(x) {
return x.search(/^(foo)?/); // NOT OK - `foo?` does not affect the returned index
}
function searchSuffix(x) {
return x.search(/(foo)?$/); // OK - `foo?` affects the returned index
}
function wordBoundary(x) {
return /\b/.test(x); // OK - some strings don't have word boundaries
}
function nonWordBoundary(x) {
return /\B/.test(x); // OK - some strings don't have non-word boundaries
}
function emptyRegex(x) {
return new RegExp("").test(x); // NOT OK
}