Skip to content

Commit

Permalink
Merge pull request github#18794 from erik-krogh/v-flag
Browse files Browse the repository at this point in the history
JS: Add support for the regex V flag
  • Loading branch information
erik-krogh authored Feb 17, 2025
2 parents a90bd68 + 6ebffd5 commit 7fa41c4
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 3 deletions.
1 change: 1 addition & 0 deletions javascript/extractor/src/com/semmle/jcorn/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ private Token readRegexp() {
String validFlags = "gim";
if (this.options.ecmaVersion() >= 6) validFlags = "gimuy";
if (this.options.ecmaVersion() >= 9) validFlags = "gimsuy";
if (this.options.ecmaVersion() >= 15) validFlags = "gimsuyv";
if (!mods.matches("^[" + validFlags + "]*$"))
this.raise(start, "Invalid regular expression flag");
if (mods.indexOf('u') >= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public static enum ECMAVersion {
ECMA2017(2017, 8),
ECMA2018(2018, 9),
ECMA2019(2019, 10),
ECMA2020(2020, 11);
ECMA2020(2020, 11),
ECMA2024(2024, 15);

private final int version;
public final int legacyVersion;
Expand Down Expand Up @@ -232,7 +233,7 @@ public Set<String> getPredefinedGlobals() {
private VirtualSourceRoot virtualSourceRoot;

public ExtractorConfig(boolean experimental) {
this.ecmaVersion = experimental ? ECMAVersion.ECMA2020 : ECMAVersion.ECMA2019;
this.ecmaVersion = experimental ? ECMAVersion.ECMA2024 : ECMAVersion.ECMA2019;
this.platform = Platform.AUTO;
this.jsx = true;
this.sourceType = SourceType.AUTO;
Expand Down
4 changes: 4 additions & 0 deletions javascript/ql/lib/change-notes/2025-02-16-v-flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added support for regular expressions using the `v` flag.
3 changes: 3 additions & 0 deletions javascript/ql/lib/semmle/javascript/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ class RegExpLiteral extends @regexp_literal, Literal, RegExpParent {
/** Holds if this regular expression has an `s` flag. */
predicate isDotAll() { RegExp::isDotAll(this.getFlags()) }

/** Holds if this regular expression has an `v` flag. */
predicate isUnicodeSets() { RegExp::isUnicodeSets(this.getFlags()) }

override string getAPrimaryQlClass() { result = "RegExpLiteral" }
}

Expand Down
4 changes: 4 additions & 0 deletions javascript/ql/lib/semmle/javascript/Regexp.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,10 @@ module RegExp {
bindingset[flags]
predicate isDotAll(string flags) { flags.matches("%s%") }

/** Holds if `flags` includes the `v` flag. */
bindingset[flags]
predicate isUnicodeSets(string flags) { flags.matches("%v%") }

/** Holds if `flags` includes the `m` flag or is the unknown flag `?`. */
bindingset[flags]
predicate maybeMultiline(string flags) { flags = unknownFlag() or isMultiline(flags) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,4 @@
| tst.js:407:128:407:129 | * | Strings starting with '0/*' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s* |
| tst.js:409:23:409:29 | [\\w.-]* | Strings starting with '//' and with many repetitions of '//' can start matching anywhere after the start of the preceeding (\\/(?:\\/[\\w.-]*)*){0,1}:([\\w.-]+) |
| tst.js:411:15:411:19 | a{1,} | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a{1,})* |
| tst.js:417:20:417:25 | (aa?)* | Strings with many repetitions of 'aa' can start matching anywhere after the start of the preceeding (aa?)*b |
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,4 @@
| tst.js:411:15:411:19 | a{1,} | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. |
| tst.js:413:25:413:35 | (\\u0000\|.)+ | This part of the regular expression may cause exponential backtracking on strings starting with '\\n\\u0000' and containing many repetitions of '\\u0000'. |
| tst.js:415:44:415:57 | (\ud83d\ude80\|.)+ | This part of the regular expression may cause exponential backtracking on strings starting with '\\n\\u{1f680}' and containing many repetitions of '\\u{1f680}'. |
| tst.js:417:22:417:23 | a? | This part of the regular expression may cause exponential backtracking on strings starting with 'a' and containing many repetitions of 'aa'. |
4 changes: 3 additions & 1 deletion javascript/ql/test/query-tests/Security/CWE-400/ReDoS/tst.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,6 @@ var bad99 = /(a{1,})*b/;

var unicode = /^\n\u0000(\u0000|.)+$/;

var largeUnicode = new RegExp("^\n\u{1F680}(\u{1F680}|.)+X$");
var largeUnicode = new RegExp("^\n\u{1F680}(\u{1F680}|.)+X$");

var unicodeSets = /(aa?)*b/v;

0 comments on commit 7fa41c4

Please sign in to comment.