Skip to content

Commit bb16731

Browse files
committed
Python: Fix for multiple parse mode flags.
1 parent dbde99d commit bb16731

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

python/ql/lib/semmle/python/regexp/internal/ParseRegExp.qll

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ class RegExp extends Expr instanceof StrConst {
617617
private predicate group_start(int start, int end) {
618618
this.non_capturing_group_start(start, end)
619619
or
620-
this.flag_group_start(start, end, _)
620+
this.flag_group_start(start, end)
621621
or
622622
this.named_group_start(start, end)
623623
or
@@ -679,20 +679,27 @@ class RegExp extends Expr instanceof StrConst {
679679
end = min(int i | i > start + 4 and this.getChar(i) = "?")
680680
}
681681

682-
private predicate flag_group_start(int start, int end, string c) {
682+
private predicate flag_group_start(int start, int end) {
683683
this.isGroupStart(start) and
684684
this.getChar(start + 1) = "?" and
685-
end = start + 3 and
686-
c = this.getChar(start + 2) and
687-
c in ["i", "L", "m", "s", "u", "x"]
685+
this.getChar(start + 2) in ["i", "L", "m", "s", "u", "x"] and
686+
end = start + 2
687+
}
688+
689+
private predicate flag_group(int start, int end, string c) {
690+
exists(int inStart, int inEnd |
691+
this.flag_group_start(start, inStart) and
692+
this.groupContents(start, end, inStart, inEnd) and
693+
this.getChar([inStart .. inEnd - 1]) = c
694+
)
688695
}
689696

690697
/**
691698
* Gets the mode of this regular expression string if
692699
* it is defined by a prefix.
693700
*/
694701
string getModeFromPrefix() {
695-
exists(string c | this.flag_group_start(_, _, c) |
702+
exists(string c | this.flag_group(_, _, c) |
696703
c = "i" and result = "IGNORECASE"
697704
or
698705
c = "L" and result = "LOCALE"

python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,5 @@
105105
| redos.py:391:15:391:25 | (\\u0061\|a)* | This part of the regular expression may cause exponential backtracking on strings starting with 'X' and containing many repetitions of 'a'. |
106106
| unittests.py:5:17:5:23 | (\u00c6\|\\\u00c6)+ | This part of the regular expression may cause exponential backtracking on strings starting with 'X' and containing many repetitions of '\u00c6'. |
107107
| unittests.py:9:16:9:24 | (?:.\|\\n)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\n'. |
108-
| unittests.py:11:20:11:28 | (?:.\|\\n)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '\\n'. |
108+
| unittests.py:11:20:11:28 | (?:.\|\\n)* | This part of the regular expression may cause exponential backtracking on strings starting with 's' and containing many repetitions of '\\n'. |
109+
| unittests.py:12:21:12:29 | (?:.\|\\n)* | This part of the regular expression may cause exponential backtracking on strings starting with 'is' and containing many repetitions of '\\n'. |

python/ql/test/query-tests/Security/CWE-730-ReDoS/unittests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
re.compile(r'(?:.|\n)*b', re.DOTALL) # Has ReDoS.
1010
re.compile(r'(?i)(?:.|\n)*b') # No ReDoS.
1111
re.compile(r'(?s)(?:.|\n)*b') # Has ReDoS.
12-
re.compile(r'(?is)(?:.|\n)*b') # Has ReDoS. [NOT DETECTED]
12+
re.compile(r'(?is)(?:.|\n)*b') # Has ReDoS.

0 commit comments

Comments
 (0)