Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e03c19b

Browse files
committed
only search prefixes/suffixes from the candidates that are used in the end
1 parent b8fabfa commit e03c19b

1 file changed

Lines changed: 16 additions & 7 deletions

File tree

javascript/ql/src/Performance/ReDoS.ql

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,8 @@ module PrefixConstruction {
953953
lastStartState(state) and
954954
result = ""
955955
or
956-
// the search stops past the last pumpable state.
957-
lengthFromStart(state) <= max(lengthFromStart(any(State s | isPumpable(s, _)))) and
956+
// the search stops past the last redos candidate state.
957+
lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and
958958
exists(State prev |
959959
// select a unique predecessor (by an arbitrary measure)
960960
prev =
@@ -982,7 +982,7 @@ module PrefixConstruction {
982982
class StateInPumpableRegexp extends State {
983983
pragma[noinline]
984984
StateInPumpableRegexp() {
985-
exists(State s | isPumpable(s, _) | getRoot(s.getRepr()) = getRoot(this.getRepr()))
985+
exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(this.getRepr()))
986986
}
987987
}
988988
}
@@ -1012,7 +1012,7 @@ module SuffixConstruction {
10121012
* are rejectable by appending some suffix.
10131013
*/
10141014
predicate reachesOnlyRejectableSuffixes(State fork, string w) {
1015-
isPumpable(fork, w) and
1015+
isReDoSCandidate(fork, w) and
10161016
forex(State next | next = process(fork, w, w.length() - 1) | isDefinitelyRejectable(next))
10171017
}
10181018

@@ -1053,7 +1053,7 @@ module SuffixConstruction {
10531053
* chars in `w` any number of times followed by the first `i+1` characters of `w`.
10541054
*/
10551055
private State process(State fork, string w, int i) {
1056-
isPumpable(fork, w) and
1056+
isReDoSCandidate(fork, w) and
10571057
exists(State prev |
10581058
i = 0 and prev = fork
10591059
or
@@ -1070,13 +1070,13 @@ module SuffixConstruction {
10701070

10711071
/**
10721072
* Holds if `term` may cause exponential backtracking on strings containing many repetitions of `witness`.
1073+
* Gets the minimum possible string that causes exponential backtracking.
10731074
*/
10741075
predicate isReDoSAttackable(RegExpTerm term, string witness, State s) {
10751076
exists(int i, string c | s = Match(term, i) |
10761077
c =
10771078
min(string w |
1078-
isPumpable(s, w) and
1079-
not isPumpable(epsilonSucc+(s), _) and
1079+
isReDoSCandidate(s, w) and
10801080
SuffixConstruction::reachesOnlyRejectableSuffixes(s, w)
10811081
|
10821082
w order by w.length(), w
@@ -1085,6 +1085,15 @@ predicate isReDoSAttackable(RegExpTerm term, string witness, State s) {
10851085
)
10861086
}
10871087

1088+
/**
1089+
* Holds if repeating `w' starting at `s` is a candidate for causing exponential backtracking.
1090+
* No check whether a rejected suffix exists has been made.
1091+
*/
1092+
predicate isReDoSCandidate(State s, string w) {
1093+
isPumpable(s, w) and
1094+
not isPumpable(epsilonSucc+(s), _)
1095+
}
1096+
10881097
/**
10891098
* Gets the result of backslash-escaping newlines, carriage-returns and
10901099
* backslashes in `s`.

0 commit comments

Comments
 (0)