Skip to content

Commit 76e3118

Browse files
authored
Commit 2: Fix \0 escape parsing
In ECMAScript std::regex, \0 matches NUL. The previous escapedCharacter arms all rejected it: the final arm's `not exists(getChar(start+1).toInt())` guard fails for "0", and the numbered-backref arm excludes 0. Add an explicit \0 case (end=start+2) guarded so the following character is not a digit, mirroring EcmaRegExp.escapedCharacter in PR #22200. Add corpus case "a\\0b" to test.cpp; \0 now parses as RegExpEscape. Bundle: github/codeql-action codeql-bundle-v2.26.1 (CodeQL CLI 2.26.1).
1 parent 448ae6a commit 76e3118

5 files changed

Lines changed: 332 additions & 302 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ class RegExp extends StringLiteral {
394394
// wide hex char \uhhhh
395395
this.getChar(start + 1) = "u" and end = start + 6
396396
or
397+
// NUL escape \0 (not followed by another digit, which would make it an octal escape)
398+
this.getChar(start + 1) = "0" and
399+
not exists(this.getChar(start + 2).toInt()) and
400+
end = start + 2
401+
or
397402
// escape not handled above; update when adding a new case
398403
not this.getChar(start + 1) in ["x", "u"] and
399404
not exists(this.getChar(start + 1).toInt()) and
Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
1-
| test.cpp:144:23:144:23 | a | 20 | 0 | 1 | 23 | 23 |
2-
| test.cpp:144:23:144:24 | a+ | 20 | 0 | 2 | 23 | 24 |
3-
| test.cpp:144:23:144:25 | a+b | 20 | 0 | 3 | 23 | 25 |
4-
| test.cpp:144:25:144:25 | b | 20 | 2 | 3 | 25 | 25 |
5-
| test.cpp:147:24:147:25 | \\s | 21 | 0 | 2 | 24 | 25 |
6-
| test.cpp:147:24:147:26 | \\s+ | 21 | 0 | 3 | 24 | 26 |
7-
| test.cpp:147:24:147:27 | \\s+$ | 21 | 0 | 4 | 24 | 27 |
8-
| test.cpp:147:27:147:27 | $ | 21 | 3 | 4 | 27 | 27 |
9-
| test.cpp:150:24:150:25 | \\( | 21 | 0 | 2 | 24 | 25 |
10-
| test.cpp:150:24:150:37 | \\(([,\\w]+)+\\)$ | 21 | 0 | 14 | 24 | 37 |
11-
| test.cpp:150:26:150:33 | ([,\\w]+) | 21 | 2 | 10 | 26 | 33 |
12-
| test.cpp:150:26:150:34 | ([,\\w]+)+ | 21 | 2 | 11 | 26 | 34 |
13-
| test.cpp:150:27:150:31 | [,\\w] | 21 | 3 | 8 | 27 | 31 |
14-
| test.cpp:150:27:150:32 | [,\\w]+ | 21 | 3 | 9 | 27 | 32 |
15-
| test.cpp:150:28:150:28 | , | 21 | 4 | 5 | 28 | 28 |
16-
| test.cpp:150:29:150:30 | \\w | 21 | 5 | 7 | 29 | 30 |
17-
| test.cpp:150:35:150:36 | \\) | 21 | 11 | 13 | 35 | 36 |
18-
| test.cpp:150:37:150:37 | $ | 21 | 13 | 14 | 37 | 37 |
19-
| test.cpp:153:25:153:25 | a | 21 | 0 | 1 | 25 | 25 |
20-
| test.cpp:153:25:153:26 | a+ | 21 | 0 | 2 | 25 | 26 |
21-
| test.cpp:153:25:153:27 | a+b | 21 | 0 | 3 | 25 | 27 |
22-
| test.cpp:153:27:153:27 | b | 21 | 2 | 3 | 27 | 27 |
23-
| test.cpp:156:24:156:24 | a | 22 | 0 | 1 | 24 | 24 |
24-
| test.cpp:156:24:156:25 | a+ | 22 | 0 | 2 | 24 | 25 |
25-
| test.cpp:156:24:156:26 | a+b | 22 | 0 | 3 | 24 | 26 |
26-
| test.cpp:156:26:156:26 | b | 22 | 2 | 3 | 26 | 26 |
27-
| test.cpp:159:30:159:30 | a | 26 | 0 | 1 | 30 | 30 |
28-
| test.cpp:159:30:159:31 | a+ | 26 | 0 | 2 | 30 | 31 |
29-
| test.cpp:159:30:159:32 | a+b | 26 | 0 | 3 | 30 | 32 |
30-
| test.cpp:159:32:159:32 | b | 26 | 2 | 3 | 32 | 32 |
31-
| test.cpp:163:22:163:23 | \\s | 21 | 0 | 2 | 22 | 23 |
32-
| test.cpp:163:22:163:24 | \\s+ | 21 | 0 | 3 | 22 | 24 |
33-
| test.cpp:166:22:166:22 | a | 21 | 0 | 1 | 22 | 22 |
34-
| test.cpp:166:22:166:25 | a\\.b | 21 | 0 | 4 | 22 | 25 |
35-
| test.cpp:166:23:166:24 | \\. | 21 | 1 | 3 | 23 | 24 |
36-
| test.cpp:166:25:166:25 | b | 21 | 3 | 4 | 25 | 25 |
1+
| test.cpp:144:23:144:23 | a | 22 | 0 | 1 | 23 | 23 |
2+
| test.cpp:144:23:144:24 | a+ | 22 | 0 | 2 | 23 | 24 |
3+
| test.cpp:144:23:144:25 | a+b | 22 | 0 | 3 | 23 | 25 |
4+
| test.cpp:144:25:144:25 | b | 22 | 2 | 3 | 25 | 25 |
5+
| test.cpp:147:23:147:23 | a | 20 | 0 | 1 | 23 | 23 |
6+
| test.cpp:147:23:147:24 | a+ | 20 | 0 | 2 | 23 | 24 |
7+
| test.cpp:147:23:147:25 | a+b | 20 | 0 | 3 | 23 | 25 |
8+
| test.cpp:147:25:147:25 | b | 20 | 2 | 3 | 25 | 25 |
9+
| test.cpp:150:24:150:25 | \\s | 21 | 0 | 2 | 24 | 25 |
10+
| test.cpp:150:24:150:26 | \\s+ | 21 | 0 | 3 | 24 | 26 |
11+
| test.cpp:150:24:150:27 | \\s+$ | 21 | 0 | 4 | 24 | 27 |
12+
| test.cpp:150:27:150:27 | $ | 21 | 3 | 4 | 27 | 27 |
13+
| test.cpp:153:24:153:25 | \\( | 21 | 0 | 2 | 24 | 25 |
14+
| test.cpp:153:24:153:37 | \\(([,\\w]+)+\\)$ | 21 | 0 | 14 | 24 | 37 |
15+
| test.cpp:153:26:153:33 | ([,\\w]+) | 21 | 2 | 10 | 26 | 33 |
16+
| test.cpp:153:26:153:34 | ([,\\w]+)+ | 21 | 2 | 11 | 26 | 34 |
17+
| test.cpp:153:27:153:31 | [,\\w] | 21 | 3 | 8 | 27 | 31 |
18+
| test.cpp:153:27:153:32 | [,\\w]+ | 21 | 3 | 9 | 27 | 32 |
19+
| test.cpp:153:28:153:28 | , | 21 | 4 | 5 | 28 | 28 |
20+
| test.cpp:153:29:153:30 | \\w | 21 | 5 | 7 | 29 | 30 |
21+
| test.cpp:153:35:153:36 | \\) | 21 | 11 | 13 | 35 | 36 |
22+
| test.cpp:153:37:153:37 | $ | 21 | 13 | 14 | 37 | 37 |
23+
| test.cpp:156:25:156:25 | a | 21 | 0 | 1 | 25 | 25 |
24+
| test.cpp:156:25:156:26 | a+ | 21 | 0 | 2 | 25 | 26 |
25+
| test.cpp:156:25:156:27 | a+b | 21 | 0 | 3 | 25 | 27 |
26+
| test.cpp:156:27:156:27 | b | 21 | 2 | 3 | 27 | 27 |
27+
| test.cpp:159:24:159:24 | a | 22 | 0 | 1 | 24 | 24 |
28+
| test.cpp:159:24:159:25 | a+ | 22 | 0 | 2 | 24 | 25 |
29+
| test.cpp:159:24:159:26 | a+b | 22 | 0 | 3 | 24 | 26 |
30+
| test.cpp:159:26:159:26 | b | 22 | 2 | 3 | 26 | 26 |
31+
| test.cpp:162:30:162:30 | a | 26 | 0 | 1 | 30 | 30 |
32+
| test.cpp:162:30:162:31 | a+ | 26 | 0 | 2 | 30 | 31 |
33+
| test.cpp:162:30:162:32 | a+b | 26 | 0 | 3 | 30 | 32 |
34+
| test.cpp:162:32:162:32 | b | 26 | 2 | 3 | 32 | 32 |
35+
| test.cpp:166:22:166:23 | \\s | 21 | 0 | 2 | 22 | 23 |
36+
| test.cpp:166:22:166:24 | \\s+ | 21 | 0 | 3 | 22 | 24 |
37+
| test.cpp:169:22:169:22 | a | 21 | 0 | 1 | 22 | 22 |
38+
| test.cpp:169:22:169:25 | a\\.b | 21 | 0 | 4 | 22 | 25 |
39+
| test.cpp:169:23:169:24 | \\. | 21 | 1 | 3 | 23 | 24 |
40+
| test.cpp:169:25:169:25 | b | 21 | 3 | 4 | 25 | 25 |

0 commit comments

Comments
 (0)