@@ -29,7 +29,7 @@ module Make<RegexTreeViewSig TreeImpl> {
29
29
*/
30
30
bindingset [ str]
31
31
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 ( )
33
33
}
34
34
35
35
/**
@@ -708,6 +708,12 @@ module Make<RegexTreeViewSig TreeImpl> {
708
708
)
709
709
}
710
710
711
+ pragma [ noinline]
712
+ private int getCodepointLengthForState ( string s ) {
713
+ result = getCodepointLength ( s ) and
714
+ s = any ( RegexpCharacterConstant reg ) .getValue ( )
715
+ }
716
+
711
717
/**
712
718
* Holds if the NFA has a transition from `q1` to `q2` labelled with `lbl`.
713
719
*/
@@ -725,7 +731,7 @@ module Make<RegexTreeViewSig TreeImpl> {
725
731
(
726
732
q2 = Match ( s , i + 1 )
727
733
or
728
- getCodepointLength ( s .getValue ( ) ) = i + 1 and
734
+ getCodepointLengthForState ( s .getValue ( ) ) = i + 1 and
729
735
q2 = after ( s )
730
736
)
731
737
)
@@ -1119,7 +1125,7 @@ module Make<RegexTreeViewSig TreeImpl> {
1119
1125
*/
1120
1126
predicate reachesOnlyRejectableSuffixes ( State fork , string w ) {
1121
1127
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 ) |
1123
1129
isLikelyRejectable ( next )
1124
1130
) and
1125
1131
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> {
1232
1238
}
1233
1239
1234
1240
// `process` can't use pragma[inline] predicates. So a materialized version of `getCodepointAt` is needed.
1241
+ pragma [ noinline]
1235
1242
private string getCodePointAtForProcess ( string str , int i ) {
1236
1243
result = getCodepointAt ( str , i ) and
1237
- exists ( getProcessPrevious ( _, _ , str ) )
1244
+ isReDoSCandidate ( _, str )
1238
1245
}
1239
1246
1240
1247
/**
@@ -1255,6 +1262,12 @@ module Make<RegexTreeViewSig TreeImpl> {
1255
1262
)
1256
1263
}
1257
1264
1265
+ pragma [ noinline]
1266
+ private int getCodepointLengthForCandidate ( string s ) {
1267
+ result = getCodepointLength ( s ) and
1268
+ isReDoSCandidate ( _, s )
1269
+ }
1270
+
1258
1271
/**
1259
1272
* Gets a state that can be reached from pumpable `fork` consuming all
1260
1273
* chars in `w` any number of times followed by the first `i` characters of `w`.
@@ -1268,7 +1281,7 @@ module Make<RegexTreeViewSig TreeImpl> {
1268
1281
or
1269
1282
// repeat until fixpoint
1270
1283
i = 0 and
1271
- result = process ( fork , w , getCodepointLength ( w ) - 1 )
1284
+ result = process ( fork , w , getCodepointLengthForCandidate ( w ) - 1 )
1272
1285
)
1273
1286
}
1274
1287
0 commit comments