diff --git a/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll b/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll index 9e659f8168a6..51454ede4e72 100644 --- a/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll +++ b/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll @@ -222,6 +222,11 @@ private module Impl implements RegexTreeViewSig { // Find the opening '"'. not re instanceof RawStringLiteral and result = 1 + min(int i | vt.charAt(i) = "\"") + or + // No opening '"'. + not re instanceof RawStringLiteral and + not exists(int i | vt.charAt(i) = "\"") and + result = 0 ) } diff --git a/cpp/ql/test/library-tests/regex/locations.expected b/cpp/ql/test/library-tests/regex/locations.expected index a9f12c020d79..5bf219789c0d 100644 --- a/cpp/ql/test/library-tests/regex/locations.expected +++ b/cpp/ql/test/library-tests/regex/locations.expected @@ -61,3 +61,6 @@ | regexp.cpp:120:41:120:44 | a\\nc | regexp.cpp | 120 | 41 | 120 | 44 | | regexp.cpp:121:25:121:28 | a\\nc | regexp.cpp | 121 | 25 | 121 | 28 | | regexp.cpp:122:29:122:32 | a\\nc | regexp.cpp | 122 | 29 | 122 | 32 | +| regexp.cpp:127:29:127:32 | abc1 | regexp.cpp | 127 | 29 | 127 | 32 | +| regexp.cpp:128:35:128:38 | abc2 | regexp.cpp | 128 | 35 | 128 | 38 | +| regexp.cpp:129:25:129:30 | xabc3x | regexp.cpp | 129 | 25 | 129 | 30 | diff --git a/cpp/ql/test/library-tests/regex/parse.expected b/cpp/ql/test/library-tests/regex/parse.expected index e8d84b277514..2c7133d90946 100644 --- a/cpp/ql/test/library-tests/regex/parse.expected +++ b/cpp/ql/test/library-tests/regex/parse.expected @@ -637,3 +637,9 @@ regexp.cpp: # 122| [RegExpConstant, RegExpEscape] \n # 122| [RegExpConstant, RegExpNormalChar] c + +# 127| [RegExpConstant, RegExpNormalChar] abc1 + +# 128| [RegExpConstant, RegExpNormalChar] abc2 + +# 129| [RegExpConstant, RegExpNormalChar] xabc3x diff --git a/cpp/ql/test/library-tests/regex/regexp.cpp b/cpp/ql/test/library-tests/regex/regexp.cpp index 51986dd59adf..785caae0db3f 100644 --- a/cpp/ql/test/library-tests/regex/regexp.cpp +++ b/cpp/ql/test/library-tests/regex/regexp.cpp @@ -120,3 +120,10 @@ std::basic_regex r_loc_uR(uR"(a\nc)"); std::basic_regex r_loc_UR(UR"(a\nc)"); std::regex r_loc_Rx(R"x(a\nc)x"); std::regex r_loc_Rfoo(R"foo(a\nc)foo"); + +// Composite and stringified string literals +#define STRINGIFY(str) #str +#define WRAP(str) "x" #str "x" +std::regex r_loc_composite("ab" "c1"); +std::regex r_loc_macro1(STRINGIFY(abc2)); +std::regex r_loc_macro2(WRAP(abc3)); diff --git a/cpp/ql/test/library-tests/regex/regexp.expected b/cpp/ql/test/library-tests/regex/regexp.expected index 6e7a4cfc7204..6980c8e3b962 100644 --- a/cpp/ql/test/library-tests/regex/regexp.expected +++ b/cpp/ql/test/library-tests/regex/regexp.expected @@ -238,6 +238,9 @@ term | regexp.cpp:122:29:122:32 | a\\nc | RegExpSequence | | regexp.cpp:122:30:122:31 | \\n | RegExpConstant,RegExpEscape | | regexp.cpp:122:32:122:32 | c | RegExpConstant,RegExpNormalChar | +| regexp.cpp:127:29:127:32 | abc1 | RegExpConstant,RegExpNormalChar | +| regexp.cpp:128:35:128:38 | abc2 | RegExpConstant,RegExpNormalChar | +| regexp.cpp:129:25:129:30 | xabc3x | RegExpConstant,RegExpNormalChar | regExpNormalCharValue | regexp.cpp:18:19:18:21 | abc | abc | | regexp.cpp:21:20:21:20 | a | a | @@ -362,3 +365,6 @@ regExpNormalCharValue | regexp.cpp:122:29:122:29 | a | a | | regexp.cpp:122:30:122:31 | \\n | \n | | regexp.cpp:122:32:122:32 | c | c | +| regexp.cpp:127:29:127:32 | abc1 | abc1 | +| regexp.cpp:128:35:128:38 | abc2 | abc2 | +| regexp.cpp:129:25:129:30 | xabc3x | xabc3x |