diff --git a/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll b/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll index 66c6031bb2e..8951df78833 100644 --- a/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll +++ b/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll @@ -502,13 +502,7 @@ abstract class RegExp extends StringLiteral { } /** Gets the name, if it has one, of the group in start,end */ - string getGroupName(int start, int end) { - this.group(start, end) and - exists(int nameEnd | - this.namedGroupStart(start, nameEnd) and - result = this.getText().substring(start + 3, nameEnd - 1) - ) - } + string getGroupName(int start, int end) { none() } /** Whether the text in the range start, end is a group and can match the empty string. */ predicate zeroWidthMatch(int start, int end) { @@ -586,8 +580,6 @@ abstract class RegExp extends StringLiteral { private predicate groupStart(int start, int end) { this.nonCapturingGroupStart(start, end) or - this.namedGroupStart(start, end) - or this.lookaheadAssertionStart(start, end) or this.negativeLookaheadAssertionStart(start, end) @@ -603,7 +595,7 @@ abstract class RegExp extends StringLiteral { private predicate nonCapturingGroupStart(int start, int end) { this.isGroupStart(start) and this.getChar(start + 1) = "?" and - this.getChar(start + 2) = [":", "=", "<", "!", "#"] and + this.getChar(start + 2) = [":", "=", "!", "#"] and end = start + 3 } @@ -614,25 +606,6 @@ abstract class RegExp extends StringLiteral { end = start + 1 } - /** - * Matches the start of a named group, such as: - * - `(?\w+)` - * - `(?'name'\w+)` - */ - private predicate namedGroupStart(int start, int end) { - this.isGroupStart(start) and - this.getChar(start + 1) = "?" and - ( - this.getChar(start + 2) = "<" and - not this.getChar(start + 3) = "=" and // (?<=foo) is a positive lookbehind assertion - not this.getChar(start + 3) = "!" and // (? start + 3 and this.getChar(i) = ">") and - end = nameEnd + 1 - ) - ) - } - /** Matches the start of a positive lookahead assertion, i.e. `(?=`. */ private predicate lookaheadAssertionStart(int start, int end) { this.isGroupStart(start) and diff --git a/cpp/ql/test/library-tests/regex/parse.expected b/cpp/ql/test/library-tests/regex/parse.expected index 5427d40f61c..b242ae94712 100644 --- a/cpp/ql/test/library-tests/regex/parse.expected +++ b/cpp/ql/test/library-tests/regex/parse.expected @@ -44,8 +44,6 @@ #-----| [RegExpConstant, RegExpNormalChar] b -#-----| [RegExpCharacterClassEscape] \w - #-----| [RegExpConstant, RegExpNormalChar] : #-----| [RegExpCharacterClassEscape] \w @@ -173,10 +171,10 @@ #-----| 0 -> [RegExpCharacterClass] [[:alpha:]] #-----| 1 -> [RegExpCharacterClass] [[:digit:]] -#-----| [RegExpSequence] (?q+)\s+\k+ -#-----| 0 -> [RegExpGroup] (?q+) +#-----| [RegExpSequence] (q+)\s+\k+ +#-----| 0 -> [RegExpGroup] (q+) #-----| 1 -> [RegExpPlus] \s+ -#-----| 2 -> [RegExpPlus] \k+ +#-----| 2 -> [RegExpPlus] \k+ #-----| [RegExpSequence] (a+)b+\1 #-----| 0 -> [RegExpGroup] (a+) @@ -237,7 +235,7 @@ #-----| 2 -> [RegExpOpt] c? #-----| 3 -> [RegExpConstant, RegExpNormalChar] d -#-----| [RegExpBackRef] \k +#-----| [RegExpBackRef] \k #-----| [RegExpBackRef] \1 @@ -249,15 +247,12 @@ #-----| [RegExpDot] . -#-----| [RegExpGroup] (?q+) +#-----| [RegExpGroup] (q+) #-----| 0 -> [RegExpPlus] q+ #-----| [RegExpGroup] (a+) #-----| 0 -> [RegExpPlus] a+ -#-----| [RegExpGroup] (?\w+) -#-----| 0 -> [RegExpPlus] \w+ - #-----| [RegExpGroup] (?::+) #-----| 0 -> [RegExpPlus] :+ @@ -364,8 +359,8 @@ #-----| [RegExpPlus] \s+ #-----| 0 -> [RegExpCharacterClassEscape] \s -#-----| [RegExpPlus] \k+ -#-----| 0 -> [RegExpBackRef] \k +#-----| [RegExpPlus] \k+ +#-----| 0 -> [RegExpBackRef] \k #-----| [RegExpPlus] a+ #-----| 0 -> [RegExpConstant, RegExpNormalChar] a @@ -373,9 +368,6 @@ #-----| [RegExpPlus] b+ #-----| 0 -> [RegExpConstant, RegExpNormalChar] b -#-----| [RegExpPlus] \w+ -#-----| 0 -> [RegExpCharacterClassEscape] \w - #-----| [RegExpPlus] :+ #-----| 0 -> [RegExpConstant, RegExpNormalChar] : diff --git a/cpp/ql/test/library-tests/regex/regexp.cpp b/cpp/ql/test/library-tests/regex/regexp.cpp index 397f28a47ab..b50fe9b65d3 100644 --- a/cpp/ql/test/library-tests/regex/regexp.cpp +++ b/cpp/ql/test/library-tests/regex/regexp.cpp @@ -58,12 +58,9 @@ std::regex r_grp2("fo(o|b)ar"); std::regex r_grp3("(a|b|cd)e"); std::regex r_grp4("(?::+)\\w"); // Non-capturing group matching colons -// Named groups -std::regex r_ng1("(?\\w+)"); - // Backreferences std::regex r_bref1("(a+)b+\\1"); -std::regex r_bref2("(?q+)\\s+\\k+"); +std::regex r_bref2("(q+)\\s+\\k+"); // Two separate character classes, each containing a single POSIX bracket expression std::regex r_posix1("[[:alpha:]][[:digit:]]"); diff --git a/cpp/ql/test/library-tests/regex/regexp.expected b/cpp/ql/test/library-tests/regex/regexp.expected index 75e66c987f5..7f6eb7afd1f 100644 --- a/cpp/ql/test/library-tests/regex/regexp.expected +++ b/cpp/ql/test/library-tests/regex/regexp.expected @@ -1,11 +1,10 @@ groupName -| file://:0:0:0:0 | (?\\w+) | id | -| file://:0:0:0:0 | (?q+) | qux | groupNumber | file://:0:0:0:0 | (a+) | 1 | | file://:0:0:0:0 | (a\|b\|cd) | 1 | | file://:0:0:0:0 | (foo) | 1 | | file://:0:0:0:0 | (o\|b) | 1 | +| file://:0:0:0:0 | (q+) | 1 | term | file://:0:0:0:0 | 0 | RegExpConstant,RegExpNormalChar | | file://:0:0:0:0 | 0-9 | RegExpCharacterRange | @@ -16,9 +15,6 @@ term | file://:0:0:0:0 | !a | RegExpConstant,RegExpNormalChar | | file://:0:0:0:0 | (?::+) | RegExpGroup | | file://:0:0:0:0 | (?::+)\\w | RegExpSequence | -| file://:0:0:0:0 | (?\\w+) | RegExpGroup | -| file://:0:0:0:0 | (?q+) | RegExpGroup | -| file://:0:0:0:0 | (?q+)\\s+\\k+ | RegExpSequence | | file://:0:0:0:0 | (a+) | RegExpGroup | | file://:0:0:0:0 | (a+)b+\\1 | RegExpSequence | | file://:0:0:0:0 | (a\|b\|cd) | RegExpGroup | @@ -27,6 +23,8 @@ term | file://:0:0:0:0 | (foo)* | RegExpStar | | file://:0:0:0:0 | (foo)*bar | RegExpSequence | | file://:0:0:0:0 | (o\|b) | RegExpGroup | +| file://:0:0:0:0 | (q+) | RegExpGroup | +| file://:0:0:0:0 | (q+)\\s+\\k+ | RegExpSequence | | file://:0:0:0:0 | - | RegExpConstant,RegExpNormalChar | | file://:0:0:0:0 | . | RegExpDot | | file://:0:0:0:0 | . | RegExpDot | @@ -74,8 +72,8 @@ term | file://:0:0:0:0 | \\b!a\\B | RegExpSequence | | file://:0:0:0:0 | \\d | RegExpCharacterClassEscape | | file://:0:0:0:0 | \\d\\D | RegExpSequence | -| file://:0:0:0:0 | \\k | RegExpBackRef | -| file://:0:0:0:0 | \\k+ | RegExpPlus | +| file://:0:0:0:0 | \\k | RegExpBackRef | +| file://:0:0:0:0 | \\k+ | RegExpPlus | | file://:0:0:0:0 | \\n | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\n | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\n\\r\\t | RegExpSequence | @@ -89,8 +87,6 @@ term | file://:0:0:0:0 | \\w | RegExpCharacterClassEscape | | file://:0:0:0:0 | \\w | RegExpCharacterClassEscape | | file://:0:0:0:0 | \\w | RegExpCharacterClassEscape | -| file://:0:0:0:0 | \\w | RegExpCharacterClassEscape | -| file://:0:0:0:0 | \\w+ | RegExpPlus | | file://:0:0:0:0 | \\w+ | RegExpPlus | | file://:0:0:0:0 | \\w+\\W | RegExpSequence | | file://:0:0:0:0 | \| | RegExpConstant,RegExpNormalChar | @@ -195,7 +191,6 @@ regExpNormalCharValue | file://:0:0:0:0 | \\w | w | | file://:0:0:0:0 | \\w | w | | file://:0:0:0:0 | \\w | w | -| file://:0:0:0:0 | \\w | w | | file://:0:0:0:0 | \| | \| | | file://:0:0:0:0 | ] | ] | | file://:0:0:0:0 | ] | ] |