Skip to content

C++ regex parse tree and RegexTreeViewSig implementation (Phase 1 of ReDoS support)#22200

Draft
jketema with Copilot wants to merge 21 commits into
mainfrom
copilot/add-cpp-regular-expression-parser
Draft

C++ regex parse tree and RegexTreeViewSig implementation (Phase 1 of ReDoS support)#22200
jketema with Copilot wants to merge 21 commits into
mainfrom
copilot/add-cpp-regular-expression-parser

Conversation

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

C++ (codeql/cpp-all) has no regex parse tree and no RegexTreeViewSig implementation, blocking instantiation of the shared codeql/regex ReDoS engines. This PR adds the self-contained foundation — parser + tree view — with no queries and no dataflow (Phase 2).

New: ParseRegExp.qll

cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll

class RegExp extends StringLiteral providing offset-span predicates for the full ECMAScript construct set:

  • Quantifiers: *, +, ?, {n}, {n,m}, {n,} (greedy and lazy)
  • Groups: (...), (?:...), (?<name>...), (?=...), (?!...), (?<=...), (?<!...)
  • Character classes/ranges, alternation, anchors (., ^, $, \b, \B)
  • Backreferences: numbered \1 and ECMAScript named \k<name>
  • Escapes: \n, \r, \t, \xhh, \uhhhh, \u{...}, identity escapes

ECMAScript semantics throughout (targeting std::regex's default mode). Phase 1 conservatively treats all StringLiterals as candidate regexes; Phase 2 will restrict via std::regex construction-site dataflow.

New: RegexTreeView.qll

cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll

private newtype TRegExpParent with 9 variants + module Impl implements RegexTreeViewSig:

  • Full term class hierarchy: RegExpQuantifier/RegExpStar/RegExpPlus/RegExpOpt/RegExpRange, RegExpAlt, RegExpSequence, RegExpGroup, RegExpCharacterClass/RegExpCharacterRange, RegExpNormalChar/RegExpEscape/RegExpCharacterClassEscape, RegExpSpecialChar, RegExpDot/RegExpAnchor/RegExpCaret/RegExpDollar/RegExpWordBoundary/RegExpNonWordBoundary, RegExpSubPattern/lookahead/lookbehind variants, RegExpBackRef, RegExpConstant
  • ECMAScript-specific decisions: isPossessive → none(), matchesAnyPrefix/AnySuffix → any(), isIgnoreCase/isDotAll → none() (conservative; TODO for Phase 2 construction-site flag detection)
  • hasLocationInfo maps term offsets back to source columns within the enclosing StringLiteral
  • Exported as both import Impl as RegexTreeView (functor argument) and import Impl (direct use)

Compile check

cpp/ql/test/library-tests/regex/CompileCheck.ql instantiates both SuperlinearBackTracking::Make<RegexTreeView> and NfaUtils::Make<RegexTreeView> to verify the signature is satisfied end-to-end.

Tests

cpp/ql/test/library-tests/regex/ — test source covering quantifiers, nested quantifiers (relevant for ReDoS: (a+)+), named groups, lookahead/lookbehind, backreferences, anchors, character classes; plus parse-tree printer (parse.ql), table query (regexp.ql), and failedToParse consistency check (Consistency.ql).

Packaging

cpp/ql/lib/qlpack.yml — adds codeql/regex: ${workspace} dependency.

Copilot AI changed the title [WIP] Add C++ regular-expression parse tree foundation C++ regex parse tree and RegexTreeViewSig implementation (Phase 1 of ReDoS support) Jul 15, 2026
Copilot AI requested a review from jketema July 15, 2026 21:51
*/

import cpp
private import semmle.code.cpp.dataflow.new.DataFlow
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
private import cpp
private import semmle.code.cpp.regex.RegexTreeView::RegexTreeView as TreeView
import codeql.regex.nfa.SuperlinearBackTracking::Make<TreeView> as SuperlinearBackTracking
private import semmle.code.cpp.ir.dataflow.DataFlow

// Instantiate the shared analysis modules with our RegexTreeView.
// If RegexTreeView does not satisfy RegexTreeViewSig, these lines cause a compile error.
private module TestSuperlinear = SuperlinearBackTracking::Make<RegexTreeView>;
// If RegexTreeView does not satisfy RegexTreeViewSig, these lines cause a compile error.
private module TestSuperlinear = SuperlinearBackTracking::Make<RegexTreeView>;

private module TestNfaUtils = NfaUtils::Make<RegexTreeView>;
@@ -0,0 +1 @@
query: Security/CWE/CWE-1333/ReDoS.ql
@@ -0,0 +1 @@
query: Security/CWE/CWE-1333/PolynomialReDoS.ql
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Comment thread cpp/ql/lib/semmle/code/cpp/regex/RegexFlowConfigs.qll Fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants