// Minimal `std::regex` / `std::basic_string` stubs sufficient for the CodeQL // C++ extractor and the ReDoS modeling tests. Real standard-library headers // are not available inside the test extractor sandbox. namespace std { template class basic_string { public: basic_string() {} basic_string(const CharT*) {} const CharT* c_str() const { return 0; } const CharT* data() const { return 0; } unsigned long size() const { return 0; } }; typedef basic_string string; typedef basic_string wstring; namespace regex_constants { // syntax_option_type constants. enum syntax_option_type { ECMAScript = 1, basic = 2, extended = 4, awk = 8, grep = 16, egrep = 32, icase = 256, nosubs = 512, optimize = 1024, collate = 2048, multiline = 4096 }; // match_flag_type constants. enum match_flag_type { match_default = 0, match_not_bol = 1, match_not_eol = 2, match_any = 16, format_default = 0, format_sed = 1, format_no_copy = 4, format_first_only = 8 }; inline syntax_option_type operator|(syntax_option_type a, syntax_option_type b) { return (syntax_option_type)((int)a | (int)b); } inline match_flag_type operator|(match_flag_type a, match_flag_type b) { return (match_flag_type)((int)a | (int)b); } } // namespace regex_constants template class basic_regex { public: typedef regex_constants::syntax_option_type flag_type; basic_regex() {} basic_regex(const CharT* p) {} basic_regex(const CharT* p, flag_type f) {} basic_regex(const basic_string& p) {} basic_regex(const basic_string& p, flag_type f) {} basic_regex& assign(const CharT* p) { return *this; } basic_regex& assign(const CharT* p, flag_type f) { return *this; } basic_regex& assign(const basic_string& p) { return *this; } basic_regex& assign(const basic_string& p, flag_type f) { return *this; } }; typedef basic_regex regex; typedef basic_regex wregex; // smatch is a match_results<...> stub. template class match_results { public: match_results() {} }; typedef match_results cmatch; typedef match_results smatch; // regex_match / regex_search overloads (subject then regex). template bool regex_match(const CharT* s, const basic_regex& re) { return false; } template bool regex_match(const basic_string& s, const basic_regex& re) { return false; } template bool regex_match(const basic_string& s, const basic_regex& re, regex_constants::match_flag_type) { return false; } template bool regex_search(const CharT* s, const basic_regex& re) { return false; } template bool regex_search(const basic_string& s, const basic_regex& re) { return false; } template bool regex_search(const basic_string& s, const basic_regex& re, regex_constants::match_flag_type) { return false; } // regex_replace: (subject, regex, replacement). template basic_string regex_replace(const basic_string& s, const basic_regex& re, const basic_string& fmt) { return basic_string(); } template basic_string regex_replace(const CharT* s, const basic_regex& re, const CharT* fmt) { return basic_string(); } // Iterator constructors: (begin, end, regex). template class regex_iterator { public: regex_iterator() {} regex_iterator(Iter b, Iter e, const basic_regex& re) {} }; template class regex_token_iterator { public: regex_token_iterator() {} regex_token_iterator(Iter b, Iter e, const basic_regex& re) {} }; } // namespace std // ----------------------------------------------------------------------------- // Phase 1 tests: syntactic constructs that the parser should recognize as // regex terms once the strings are used as regexes. These literals now // flow to a `std::regex` construction site. // ----------------------------------------------------------------------------- void basic_sequence() { std::regex r1("abc"); // NOT a `RegExp` (no +, *, {n,}) } void repetition() { std::regex r1("a*b+c?d"); // RegExp std::regex r2("a{4,8}"); // NOT a RegExp (bounded) std::regex r3("a{3,}"); // RegExp (unbounded {n,}) std::regex r4("a{7}"); // NOT a RegExp } void alternation() { std::regex r1("foo|bar+"); // RegExp } void character_classes() { std::regex r1("[abc]+"); // RegExp std::regex r2("[a-fA-F0-9_]+"); // RegExp std::regex r3("[\\w]+"); // RegExp std::regex r4("[^A-Z]*"); // RegExp } void meta_classes() { std::regex r1(".*"); // RegExp std::regex r2("\\w+\\W"); // RegExp std::regex r3("\\s+\\S"); // RegExp std::regex r4("\\d+\\D"); // RegExp } void anchors() { std::regex r1("^a+bc$"); // RegExp std::regex r2("\\ba+bc\\B"); // RegExp } void groups() { std::regex r1("(foo)*bar"); // RegExp std::regex r2("fo(o|b+)ar"); // RegExp std::regex r3("(a|b|cd)e+"); // RegExp std::regex r4("(?::+)\\w"); // RegExp } void named_groups() { std::regex r1("(?\\w+)"); // RegExp std::regex r2("(?[a-z]+)(?[0-9]+)"); // RegExp } void backreferences() { std::regex r1("(a+)b+\\1"); // RegExp std::regex r2("(?q+)\\s+\\k+"); // RegExp } void lookahead_lookbehind() { std::regex r1("(?=\\w+)abc"); // RegExp std::regex r2("(?!\\d+)abc"); // RegExp std::regex r3("a+bc(?<=\\w)"); // RegExp std::regex r4("a+bc(?` constructor applies directly. std::regex r1(u8"a+b"); std::regex r2(u8R"(a+b)"); } #endif