Skip to content

Commit fe54256

Browse files
committed
fix performance
1 parent 0bce424 commit fe54256

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

shared/regex/codeql/regex/nfa/NfaUtils.qll

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ module Make<RegexTreeViewSig TreeImpl> {
2929
*/
3030
bindingset[str]
3131
private int getCodepointLength(string str) {
32-
result = max(int m | exists(str.regexpFind("(.|\\s)", m - 1, _)) or m = 0)
32+
result = str.regexpReplaceAll("(.|\\s)", "x").length()
3333
}
3434

3535
/**
@@ -708,6 +708,12 @@ module Make<RegexTreeViewSig TreeImpl> {
708708
)
709709
}
710710

711+
pragma[noinline]
712+
private int getCodepointLengthForState(string s) {
713+
result = getCodepointLength(s) and
714+
s = any(RegexpCharacterConstant reg).getValue()
715+
}
716+
711717
/**
712718
* Holds if the NFA has a transition from `q1` to `q2` labelled with `lbl`.
713719
*/
@@ -725,7 +731,7 @@ module Make<RegexTreeViewSig TreeImpl> {
725731
(
726732
q2 = Match(s, i + 1)
727733
or
728-
getCodepointLength(s.getValue()) = i + 1 and
734+
getCodepointLengthForState(s.getValue()) = i + 1 and
729735
q2 = after(s)
730736
)
731737
)
@@ -1119,7 +1125,7 @@ module Make<RegexTreeViewSig TreeImpl> {
11191125
*/
11201126
predicate reachesOnlyRejectableSuffixes(State fork, string w) {
11211127
isReDoSCandidate(fork, w) and
1122-
forex(State next | next = process(fork, w, getCodepointLength(w) - 1) |
1128+
forex(State next | next = process(fork, w, getCodepointLengthForCandidate(w) - 1) |
11231129
isLikelyRejectable(next)
11241130
) and
11251131
not getProcessPrevious(fork, _, w) = acceptsAnySuffix() // we stop `process(..)` early if we can, check here if it happened.
@@ -1232,9 +1238,10 @@ module Make<RegexTreeViewSig TreeImpl> {
12321238
}
12331239

12341240
// `process` can't use pragma[inline] predicates. So a materialized version of `getCodepointAt` is needed.
1241+
pragma[noinline]
12351242
private string getCodePointAtForProcess(string str, int i) {
12361243
result = getCodepointAt(str, i) and
1237-
exists(getProcessPrevious(_, _, str))
1244+
isReDoSCandidate(_, str)
12381245
}
12391246

12401247
/**
@@ -1255,6 +1262,12 @@ module Make<RegexTreeViewSig TreeImpl> {
12551262
)
12561263
}
12571264

1265+
pragma[noinline]
1266+
private int getCodepointLengthForCandidate(string s) {
1267+
result = getCodepointLength(s) and
1268+
isReDoSCandidate(_, s)
1269+
}
1270+
12581271
/**
12591272
* Gets a state that can be reached from pumpable `fork` consuming all
12601273
* chars in `w` any number of times followed by the first `i` characters of `w`.
@@ -1268,7 +1281,7 @@ module Make<RegexTreeViewSig TreeImpl> {
12681281
or
12691282
// repeat until fixpoint
12701283
i = 0 and
1271-
result = process(fork, w, getCodepointLength(w) - 1)
1284+
result = process(fork, w, getCodepointLengthForCandidate(w) - 1)
12721285
)
12731286
}
12741287

0 commit comments

Comments
 (0)