mirror of
https://github.com/github/codeql.git
synced 2026-07-31 15:33:00 +02:00
Commit 6: Fix POSIX-bracket mis-parses revealed by Commit 5
POSIX bracket expressions ([:name:], [.x.], [=x=]) are only valid nested
inside another character class in std::regex. The three predicates now
additionally require that at position `start` we are inside an outer
character class, approximated by requiring more non-escaped `[` than
non-escaped `]` before `start`. A well-formed POSIX bracket contributes
one `[` and one `]` at/after `start`, so the check is unaffected by
earlier POSIX brackets.
Also stop emitting individual charSetTokens for characters inside a
POSIX bracket (`inAnyPosixBracket` guard), which removes the spurious
`[RegExpCharacterRange] :]-z` on [[:alpha:]-z].
Post-fix, unnested `[:digit:]`, `[:alpha:]`, and `a[🅱️]c` are correctly
parsed as ordinary character classes / literal sequences rather than
`RegExpNamedCharacterProperty`; and the [[:alpha:]-z] range no longer
crosses the POSIX bracket boundary.
Bundle: github/codeql-action codeql-bundle-v2.26.1 (CodeQL CLI 2.26.1).
This commit is contained in:
committed by
GitHub
parent
8d53e365d6
commit
bfb7b1d046
@@ -162,7 +162,9 @@ class RegExp extends StringLiteral {
|
||||
or
|
||||
this.namedCharacterProperty(start, end, _)
|
||||
or
|
||||
exists(this.nonEscapedCharAt(start)) and end = start + 1
|
||||
exists(this.nonEscapedCharAt(start)) and
|
||||
not this.inAnyPosixBracket(start) and
|
||||
end = start + 1
|
||||
)
|
||||
or
|
||||
this.charSetToken(charsetStart, _, start) and
|
||||
@@ -172,6 +174,7 @@ class RegExp extends StringLiteral {
|
||||
this.namedCharacterProperty(start, end, _)
|
||||
or
|
||||
exists(this.nonEscapedCharAt(start)) and
|
||||
not this.inAnyPosixBracket(start) and
|
||||
end = start + 1 and
|
||||
not this.getChar(start) = "]"
|
||||
)
|
||||
@@ -313,6 +316,13 @@ class RegExp extends StringLiteral {
|
||||
private predicate posixStyleNamedCharacterProperty(int start, int end, string name) {
|
||||
this.getChar(start) = "[" and
|
||||
this.getChar(start + 1) = ":" and
|
||||
// POSIX bracket expressions are only valid nested inside another character
|
||||
// class. Approximate this by requiring at least one more (non-escaped)
|
||||
// opening `[` than closing `]` before `start`. A well-formed POSIX bracket
|
||||
// contributes one `[` and one `]` at/after `start`, so this check is
|
||||
// unaffected by other POSIX brackets earlier in the text.
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "[") >
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "]") and
|
||||
end =
|
||||
min(int e |
|
||||
e > start and
|
||||
@@ -337,6 +347,8 @@ class RegExp extends StringLiteral {
|
||||
private predicate posixCollatingSymbol(int start, int end, string name) {
|
||||
this.getChar(start) = "[" and
|
||||
this.getChar(start + 1) = "." and
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "[") >
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "]") and
|
||||
end =
|
||||
min(int e |
|
||||
e > start and
|
||||
@@ -355,6 +367,8 @@ class RegExp extends StringLiteral {
|
||||
private predicate posixEquivalenceClass(int start, int end, string name) {
|
||||
this.getChar(start) = "[" and
|
||||
this.getChar(start + 1) = "=" and
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "[") >
|
||||
count(int p | p < start and this.nonEscapedCharAt(p) = "]") and
|
||||
end =
|
||||
min(int e |
|
||||
e > start and
|
||||
|
||||
@@ -6,10 +6,19 @@
|
||||
| test.cpp:143:29:143:29 | p | 23 | 5 | 6 | 29 | 29 |
|
||||
| test.cpp:143:30:143:30 | h | 23 | 6 | 7 | 30 | 30 |
|
||||
| test.cpp:143:31:143:31 | a | 23 | 7 | 8 | 31 | 31 |
|
||||
| test.cpp:146:24:146:35 | []a[:alpha:] | 23 | 0 | 12 | 24 | 35 |
|
||||
| test.cpp:146:24:146:36 | []a[:alpha:]] | 23 | 0 | 13 | 24 | 36 |
|
||||
| test.cpp:146:25:146:25 | ] | 23 | 1 | 2 | 25 | 25 |
|
||||
| test.cpp:146:26:146:26 | a | 23 | 2 | 3 | 26 | 26 |
|
||||
| test.cpp:146:27:146:35 | [:alpha:] | 23 | 3 | 12 | 27 | 35 |
|
||||
| test.cpp:146:27:146:27 | [ | 23 | 3 | 4 | 27 | 27 |
|
||||
| test.cpp:146:28:146:28 | : | 23 | 4 | 5 | 28 | 28 |
|
||||
| test.cpp:146:29:146:29 | a | 23 | 5 | 6 | 29 | 29 |
|
||||
| test.cpp:146:30:146:30 | l | 23 | 6 | 7 | 30 | 30 |
|
||||
| test.cpp:146:31:146:31 | p | 23 | 7 | 8 | 31 | 31 |
|
||||
| test.cpp:146:32:146:32 | h | 23 | 8 | 9 | 32 | 32 |
|
||||
| test.cpp:146:33:146:33 | a | 23 | 9 | 10 | 33 | 33 |
|
||||
| test.cpp:146:34:146:34 | : | 23 | 10 | 11 | 34 | 34 |
|
||||
| test.cpp:146:36:146:36 | ] | 23 | 12 | 13 | 36 | 36 |
|
||||
| test.cpp:149:25:149:53 | [[:alpha:][:digit:][:space:]] | 24 | 0 | 29 | 25 | 53 |
|
||||
| test.cpp:149:26:149:34 | [:alpha:] | 24 | 1 | 10 | 26 | 34 |
|
||||
| test.cpp:149:35:149:43 | [:digit:] | 24 | 10 | 19 | 35 | 43 |
|
||||
|
||||
@@ -515,26 +515,81 @@ test.cpp:
|
||||
|
||||
# 128| [RegExpConstant, RegExpNormalChar] f
|
||||
|
||||
# 131| [RegExpNamedCharacterProperty] [:digit:]
|
||||
# 131| [RegExpCharacterClass] [:digit:]
|
||||
#-----| 0 -> [RegExpConstant, RegExpNormalChar] :
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] d
|
||||
#-----| 2 -> [RegExpConstant, RegExpNormalChar] i
|
||||
#-----| 3 -> [RegExpConstant, RegExpNormalChar] g
|
||||
#-----| 4 -> [RegExpConstant, RegExpNormalChar] i
|
||||
#-----| 5 -> [RegExpConstant, RegExpNormalChar] t
|
||||
#-----| 6 -> [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 134| [RegExpNamedCharacterProperty] [:alpha:]
|
||||
# 131| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] d
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] i
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] g
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] i
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] t
|
||||
|
||||
# 131| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 134| [RegExpCharacterClass] [:alpha:]
|
||||
#-----| 0 -> [RegExpConstant, RegExpNormalChar] :
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 2 -> [RegExpConstant, RegExpNormalChar] l
|
||||
#-----| 3 -> [RegExpConstant, RegExpNormalChar] p
|
||||
#-----| 4 -> [RegExpConstant, RegExpNormalChar] h
|
||||
#-----| 5 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 6 -> [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] l
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] p
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] h
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 134| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 137| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 137| [RegExpNamedCharacterProperty] [:b:]
|
||||
# 137| [RegExpSequence] a[:b:]c
|
||||
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 1 -> [RegExpCharacterClass] [:b:]
|
||||
#-----| 2 -> [RegExpConstant, RegExpNormalChar] c
|
||||
|
||||
# 137| [RegExpCharacterClass] [:b:]
|
||||
#-----| 0 -> [RegExpConstant, RegExpNormalChar] :
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] b
|
||||
#-----| 2 -> [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 137| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 137| [RegExpConstant, RegExpNormalChar] b
|
||||
|
||||
# 137| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 137| [RegExpConstant, RegExpNormalChar] c
|
||||
|
||||
# 140| [RegExpCharacterClass] [[:alpha:]-z]
|
||||
#-----| 0 -> [RegExpNamedCharacterProperty] [:alpha:]
|
||||
#-----| 0 -> [RegExpCharacterRange] [:alpha:]-z
|
||||
|
||||
# 140| [RegExpNamedCharacterProperty] [:alpha:]
|
||||
|
||||
# 140| [RegExpCharacterRange] :]-z
|
||||
# 140| [RegExpCharacterRange] [:alpha:]-z
|
||||
#-----| 0 -> [RegExpNamedCharacterProperty] [:alpha:]
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] z
|
||||
|
||||
# 140| [RegExpConstant, RegExpNormalChar] -
|
||||
|
||||
# 140| [RegExpConstant, RegExpNormalChar] z
|
||||
|
||||
# 143| [RegExpCharacterClass] [[:alpha]
|
||||
@@ -560,16 +615,43 @@ test.cpp:
|
||||
|
||||
# 143| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 146| [RegExpCharacterClass] []a[:alpha:]]
|
||||
# 146| [RegExpCharacterClass] []a[:alpha:]
|
||||
#-----| 0 -> [RegExpConstant, RegExpNormalChar] ]
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 2 -> [RegExpNamedCharacterProperty] [:alpha:]
|
||||
#-----| 2 -> [RegExpConstant, RegExpNormalChar] [
|
||||
#-----| 3 -> [RegExpConstant, RegExpNormalChar] :
|
||||
#-----| 4 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 5 -> [RegExpConstant, RegExpNormalChar] l
|
||||
#-----| 6 -> [RegExpConstant, RegExpNormalChar] p
|
||||
#-----| 7 -> [RegExpConstant, RegExpNormalChar] h
|
||||
#-----| 8 -> [RegExpConstant, RegExpNormalChar] a
|
||||
#-----| 9 -> [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 146| [RegExpSequence] []a[:alpha:]]
|
||||
#-----| 0 -> [RegExpCharacterClass] []a[:alpha:]
|
||||
#-----| 1 -> [RegExpConstant, RegExpNormalChar] ]
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] ]
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 146| [RegExpNamedCharacterProperty] [:alpha:]
|
||||
# 146| [RegExpConstant, RegExpNormalChar] [
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] l
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] p
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] h
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] a
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] :
|
||||
|
||||
# 146| [RegExpConstant, RegExpNormalChar] ]
|
||||
|
||||
# 149| [RegExpCharacterClass] [[:alpha:][:digit:][:space:]]
|
||||
#-----| 0 -> [RegExpNamedCharacterProperty] [:alpha:]
|
||||
|
||||
@@ -200,15 +200,32 @@ term
|
||||
| test.cpp:128:37:128:37 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:128:37:128:39 | a-f | RegExpCharacterRange |
|
||||
| test.cpp:128:39:128:39 | f | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:24:131:32 | [:digit:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:134:24:134:32 | [:alpha:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:131:24:131:32 | [:digit:] | RegExpCharacterClass |
|
||||
| test.cpp:131:25:131:25 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:26:131:26 | d | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:27:131:27 | i | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:28:131:28 | g | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:29:131:29 | i | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:30:131:30 | t | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:131:31:131:31 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:24:134:32 | [:alpha:] | RegExpCharacterClass |
|
||||
| test.cpp:134:25:134:25 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:26:134:26 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:27:134:27 | l | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:28:134:28 | p | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:29:134:29 | h | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:30:134:30 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:134:31:134:31 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:137:24:137:24 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:137:25:137:29 | [:b:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:137:24:137:30 | a[:b:]c | RegExpSequence |
|
||||
| test.cpp:137:25:137:29 | [:b:] | RegExpCharacterClass |
|
||||
| test.cpp:137:26:137:26 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:137:27:137:27 | b | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:137:28:137:28 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:137:30:137:30 | c | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:140:24:140:36 | [[:alpha:]-z] | RegExpCharacterClass |
|
||||
| test.cpp:140:25:140:33 | [:alpha:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:140:32:140:35 | :]-z | RegExpCharacterRange |
|
||||
| test.cpp:140:34:140:34 | - | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:140:25:140:35 | [:alpha:]-z | RegExpCharacterRange |
|
||||
| test.cpp:140:35:140:35 | z | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:143:24:143:32 | [[:alpha] | RegExpCharacterClass |
|
||||
| test.cpp:143:25:143:25 | [ | RegExpConstant,RegExpNormalChar |
|
||||
@@ -218,10 +235,19 @@ term
|
||||
| test.cpp:143:29:143:29 | p | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:143:30:143:30 | h | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:143:31:143:31 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:24:146:36 | []a[:alpha:]] | RegExpCharacterClass |
|
||||
| test.cpp:146:24:146:35 | []a[:alpha:] | RegExpCharacterClass |
|
||||
| test.cpp:146:24:146:36 | []a[:alpha:]] | RegExpSequence |
|
||||
| test.cpp:146:25:146:25 | ] | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:26:146:26 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:27:146:35 | [:alpha:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:146:27:146:27 | [ | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:28:146:28 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:29:146:29 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:30:146:30 | l | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:31:146:31 | p | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:32:146:32 | h | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:33:146:33 | a | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:34:146:34 | : | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:146:36:146:36 | ] | RegExpConstant,RegExpNormalChar |
|
||||
| test.cpp:149:25:149:53 | [[:alpha:][:digit:][:space:]] | RegExpCharacterClass |
|
||||
| test.cpp:149:26:149:34 | [:alpha:] | RegExpNamedCharacterProperty |
|
||||
| test.cpp:149:35:149:43 | [:digit:] | RegExpNamedCharacterProperty |
|
||||
@@ -377,9 +403,25 @@ regExpNormalCharValue
|
||||
| test.cpp:128:27:128:27 | F | F |
|
||||
| test.cpp:128:37:128:37 | a | a |
|
||||
| test.cpp:128:39:128:39 | f | f |
|
||||
| test.cpp:131:25:131:25 | : | : |
|
||||
| test.cpp:131:26:131:26 | d | d |
|
||||
| test.cpp:131:27:131:27 | i | i |
|
||||
| test.cpp:131:28:131:28 | g | g |
|
||||
| test.cpp:131:29:131:29 | i | i |
|
||||
| test.cpp:131:30:131:30 | t | t |
|
||||
| test.cpp:131:31:131:31 | : | : |
|
||||
| test.cpp:134:25:134:25 | : | : |
|
||||
| test.cpp:134:26:134:26 | a | a |
|
||||
| test.cpp:134:27:134:27 | l | l |
|
||||
| test.cpp:134:28:134:28 | p | p |
|
||||
| test.cpp:134:29:134:29 | h | h |
|
||||
| test.cpp:134:30:134:30 | a | a |
|
||||
| test.cpp:134:31:134:31 | : | : |
|
||||
| test.cpp:137:24:137:24 | a | a |
|
||||
| test.cpp:137:26:137:26 | : | : |
|
||||
| test.cpp:137:27:137:27 | b | b |
|
||||
| test.cpp:137:28:137:28 | : | : |
|
||||
| test.cpp:137:30:137:30 | c | c |
|
||||
| test.cpp:140:34:140:34 | - | - |
|
||||
| test.cpp:140:35:140:35 | z | z |
|
||||
| test.cpp:143:25:143:25 | [ | [ |
|
||||
| test.cpp:143:26:143:26 | : | : |
|
||||
@@ -390,6 +432,15 @@ regExpNormalCharValue
|
||||
| test.cpp:143:31:143:31 | a | a |
|
||||
| test.cpp:146:25:146:25 | ] | ] |
|
||||
| test.cpp:146:26:146:26 | a | a |
|
||||
| test.cpp:146:27:146:27 | [ | [ |
|
||||
| test.cpp:146:28:146:28 | : | : |
|
||||
| test.cpp:146:29:146:29 | a | a |
|
||||
| test.cpp:146:30:146:30 | l | l |
|
||||
| test.cpp:146:31:146:31 | p | p |
|
||||
| test.cpp:146:32:146:32 | h | h |
|
||||
| test.cpp:146:33:146:33 | a | a |
|
||||
| test.cpp:146:34:146:34 | : | : |
|
||||
| test.cpp:146:36:146:36 | ] | ] |
|
||||
| test.cpp:163:21:163:26 | \\u9879 | \u9879 |
|
||||
| test.cpp:171:23:171:23 | a | a |
|
||||
| test.cpp:171:25:171:25 | b | b |
|
||||
|
||||
Reference in New Issue
Block a user