From 0323da39c99d596ea6010f3f24f630b3391fcbf5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Jul 2026 10:13:23 +0000 Subject: [PATCH] C++: Remove named backreferences --- .../code/cpp/regex/internal/ParseRegExp.qll | 16 +------------ .../test/library-tests/regex/parse.expected | 23 ------------------- cpp/ql/test/library-tests/regex/regexp.cpp | 1 - .../test/library-tests/regex/regexp.expected | 11 --------- 4 files changed, 1 insertion(+), 50 deletions(-) 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 8951df78833..baa8d6c3556 100644 --- a/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll +++ b/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll @@ -337,7 +337,6 @@ abstract class RegExp extends StringLiteral { predicate escapedCharacter(int start, int end) { this.escapingChar(start) and not this.numberedBackreference(start, _, _) and - not this.namedBackreference(start, _, _) and ( // hex char \xhh this.getChar(start + 1) = "x" and end = start + 4 @@ -648,17 +647,6 @@ abstract class RegExp extends StringLiteral { this.isGroupEnd(inEnd) } - /** Matches a named backreference, e.g. `\k`. */ - predicate namedBackreference(int start, int end, string name) { - this.escapingChar(start) and - this.getChar(start + 1) = "k" and - this.getChar(start + 2) = "<" and - exists(int nameEnd | nameEnd = min(int i | i > start + 3 and this.getChar(i) = ">") | - end = nameEnd + 1 and - name = this.getText().substring(start + 3, nameEnd) - ) - } - /** Matches a numbered backreference, e.g. `\1`. */ predicate numberedBackreference(int start, int end, int value) { this.escapingChar(start) and @@ -678,15 +666,13 @@ abstract class RegExp extends StringLiteral { /** Whether the text in the range `start,end` is a back reference */ predicate backreference(int start, int end) { this.numberedBackreference(start, end, _) - or - this.namedBackreference(start, end, _) } /** Gets the number of the back reference in start,end */ int getBackRefNumber(int start, int end) { this.numberedBackreference(start, end, result) } /** Gets the name, if it has one, of the back reference in start,end */ - string getBackRefName(int start, int end) { this.namedBackreference(start, end, result) } + string getBackRefName(int start, int end) { none() } private predicate baseItem(int start, int end) { this.characterItem(start, end) and diff --git a/cpp/ql/test/library-tests/regex/parse.expected b/cpp/ql/test/library-tests/regex/parse.expected index b242ae94712..2224556cd52 100644 --- a/cpp/ql/test/library-tests/regex/parse.expected +++ b/cpp/ql/test/library-tests/regex/parse.expected @@ -36,10 +36,6 @@ #-----| [RegExpConstant, RegExpNormalChar] f -#-----| [RegExpConstant, RegExpNormalChar] q - -#-----| [RegExpCharacterClassEscape] \s - #-----| [RegExpConstant, RegExpNormalChar] a #-----| [RegExpConstant, RegExpNormalChar] b @@ -171,11 +167,6 @@ #-----| 0 -> [RegExpCharacterClass] [[:alpha:]] #-----| 1 -> [RegExpCharacterClass] [[:digit:]] -#-----| [RegExpSequence] (q+)\s+\k+ -#-----| 0 -> [RegExpGroup] (q+) -#-----| 1 -> [RegExpPlus] \s+ -#-----| 2 -> [RegExpPlus] \k+ - #-----| [RegExpSequence] (a+)b+\1 #-----| 0 -> [RegExpGroup] (a+) #-----| 1 -> [RegExpPlus] b+ @@ -235,8 +226,6 @@ #-----| 2 -> [RegExpOpt] c? #-----| 3 -> [RegExpConstant, RegExpNormalChar] d -#-----| [RegExpBackRef] \k - #-----| [RegExpBackRef] \1 #-----| [RegExpSpecialChar] \b @@ -247,9 +236,6 @@ #-----| [RegExpDot] . -#-----| [RegExpGroup] (q+) -#-----| 0 -> [RegExpPlus] q+ - #-----| [RegExpGroup] (a+) #-----| 0 -> [RegExpPlus] a+ @@ -353,15 +339,6 @@ #-----| 0 -> [RegExpConstant, RegExpNormalChar] foo #-----| 1 -> [RegExpConstant, RegExpNormalChar] bar -#-----| [RegExpPlus] q+ -#-----| 0 -> [RegExpConstant, RegExpNormalChar] q - -#-----| [RegExpPlus] \s+ -#-----| 0 -> [RegExpCharacterClassEscape] \s - -#-----| [RegExpPlus] \k+ -#-----| 0 -> [RegExpBackRef] \k - #-----| [RegExpPlus] a+ #-----| 0 -> [RegExpConstant, RegExpNormalChar] a diff --git a/cpp/ql/test/library-tests/regex/regexp.cpp b/cpp/ql/test/library-tests/regex/regexp.cpp index b50fe9b65d3..3f8330a0a59 100644 --- a/cpp/ql/test/library-tests/regex/regexp.cpp +++ b/cpp/ql/test/library-tests/regex/regexp.cpp @@ -60,7 +60,6 @@ std::regex r_grp4("(?::+)\\w"); // Non-capturing group matching colons // Backreferences std::regex r_bref1("(a+)b+\\1"); -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 7f6eb7afd1f..ddac96dd553 100644 --- a/cpp/ql/test/library-tests/regex/regexp.expected +++ b/cpp/ql/test/library-tests/regex/regexp.expected @@ -4,7 +4,6 @@ groupNumber | 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 | @@ -23,8 +22,6 @@ 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 | @@ -72,15 +69,11 @@ 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 | \\n | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\n | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\n\\r\\t | RegExpSequence | | file://:0:0:0:0 | \\r | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\s | RegExpCharacterClassEscape | -| file://:0:0:0:0 | \\s | RegExpCharacterClassEscape | -| file://:0:0:0:0 | \\s+ | RegExpPlus | | file://:0:0:0:0 | \\s\\S | RegExpSequence | | file://:0:0:0:0 | \\t | RegExpConstant,RegExpEscape | | file://:0:0:0:0 | \\u{987 | RegExpConstant,RegExpEscape | @@ -156,8 +149,6 @@ term | file://:0:0:0:0 | foo\|bar | RegExpAlt | | file://:0:0:0:0 | o | RegExpConstant,RegExpNormalChar | | file://:0:0:0:0 | o\|b | RegExpAlt | -| file://:0:0:0:0 | q | RegExpConstant,RegExpNormalChar | -| file://:0:0:0:0 | q+ | RegExpPlus | regExpNormalCharValue | file://:0:0:0:0 | 0 | 0 | | file://:0:0:0:0 | 1 | 1 | @@ -185,7 +176,6 @@ regExpNormalCharValue | file://:0:0:0:0 | \\n | \n | | file://:0:0:0:0 | \\r | \r | | file://:0:0:0:0 | \\s | s | -| file://:0:0:0:0 | \\s | s | | file://:0:0:0:0 | \\t | \t | | file://:0:0:0:0 | \\u{987 | \u0987 | | file://:0:0:0:0 | \\w | w | @@ -240,4 +230,3 @@ regExpNormalCharValue | file://:0:0:0:0 | foo | foo | | file://:0:0:0:0 | foo | foo | | file://:0:0:0:0 | o | o | -| file://:0:0:0:0 | q | q |