99 * Theorem 3 from the paper describes the basic idea.
1010 *
1111 * The following explains the idea using variables and predicate names that are used in the implementation:
12- * We consider a pair of repetitions, which we will call `pivot` and `succ `.
12+ * We consider a pair of repetitions, which we will call `pivot` and `pumpEnd `.
1313 *
1414 * We create a product automaton of 3-tuples of states (see `StateTuple`).
1515 * There exists a transition `(a,b,c) -> (d,e,f)` in the product automaton
1616 * iff there exists three transitions in the NFA `a->d, b->e, c->f` where those three
1717 * transitions all match a shared character `char`. (see `getAThreewayIntersect`)
1818 *
19- * We start a search in the product automaton at `(pivot, pivot, succ )`,
19+ * We start a search in the product automaton at `(pivot, pivot, pumpEnd )`,
2020 * and search for a series of transitions (a `Trace`), such that we end
21- * at `(pivot, succ, succ )` (see `isReachableFromStartTuple`).
21+ * at `(pivot, pumpEnd, pumpEnd )` (see `isReachableFromStartTuple`).
2222 *
2323 * For example, consider the regular expression `/^\d*5\w*$/`.
2424 * The search will start at the tuple `(\d*, \d*, \w*)` and search
@@ -52,29 +52,29 @@ module Make<RegexTreeViewSig TreeImpl> {
5252
5353 private newtype TStateTuple =
5454 /**
55- * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, succ )`.
55+ * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, pumpEnd )`.
5656 */
57- MkStateTuple ( State pivot , State succ , State q1 , State q2 , State q3 ) {
58- // starts at (pivot, pivot, succ )
57+ MkStateTuple ( State pivot , State pumpEnd , State q1 , State q2 , State q3 ) {
58+ // starts at (pivot, pivot, pumpEnd )
5959 isStartLoops ( q1 , q3 ) and
6060 q1 = q2 and
6161 pivot = q1 and
62- succ = q3
62+ pumpEnd = q3
6363 or
6464 // recurse: any transition out where all 3 edges share a char (and the resulting tuple isn't obviously infeasible)
6565 exists ( StateTuple prev |
66- prev = MkStateTuple ( pivot , succ , _, _, _) and
66+ prev = MkStateTuple ( pivot , pumpEnd , _, _, _) and
6767 hasCommonStep ( prev , _, _, _, q1 , q2 , q3 ) and
68- FeasibleTuple:: isFeasibleTuple ( pivot , succ , q1 , q2 , q3 )
68+ FeasibleTuple:: isFeasibleTuple ( pivot , pumpEnd , q1 , q2 , q3 )
6969 )
7070 }
7171
7272 /**
73- * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, succ )`.
73+ * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, pumpEnd )`.
7474 *
7575 * We lazily only construct those states that we are actually
7676 * going to need.
77- * Either a start state `(pivot, pivot, succ )`, or a state
77+ * Either a start state `(pivot, pivot, pumpEnd )`, or a state
7878 * where there exists a transition from an already existing state.
7979 *
8080 * The exponential variant of this query (`js/redos`) uses an optimization
@@ -83,12 +83,12 @@ module Make<RegexTreeViewSig TreeImpl> {
8383 */
8484 class StateTuple extends TStateTuple {
8585 State pivot ;
86- State succ ;
86+ State pumpEnd ;
8787 State q1 ;
8888 State q2 ;
8989 State q3 ;
9090
91- StateTuple ( ) { this = MkStateTuple ( pivot , succ , q1 , q2 , q3 ) }
91+ StateTuple ( ) { this = MkStateTuple ( pivot , pumpEnd , q1 , q2 , q3 ) }
9292
9393 /**
9494 * Gest a string representation of this tuple.
@@ -122,9 +122,9 @@ module Make<RegexTreeViewSig TreeImpl> {
122122 State getPivot ( ) { result = pivot }
123123
124124 /**
125- * Gets the succ state.
125+ * Gets the pumpEnd state.
126126 */
127- State getSucc ( ) { result = succ }
127+ State getPumpEnd ( ) { result = pumpEnd }
128128
129129 /**
130130 * Holds if the pivot state has the specified location.
@@ -142,17 +142,17 @@ module Make<RegexTreeViewSig TreeImpl> {
142142 */
143143 private module FeasibleTuple {
144144 /**
145- * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, succ )` to an end-state `(pivot, succ, succ )` in the product automaton.
145+ * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, pumpEnd )` to an end-state `(pivot, pumpEnd, pumpEnd )` in the product automaton.
146146 */
147- bindingset [ pivot, succ , r1, r2, r3]
147+ bindingset [ pivot, pumpEnd , r1, r2, r3]
148148 pragma [ inline_late]
149- predicate isFeasibleTuple ( State pivot , State succ , State r1 , State r2 , State r3 ) {
150- isStartLoops ( pivot , succ ) and
149+ predicate isFeasibleTuple ( State pivot , State pumpEnd , State r1 , State r2 , State r3 ) {
150+ isStartLoops ( pivot , pumpEnd ) and
151151 // r1 can reach the pivot state
152152 reachesBeginning ( r1 , pivot ) and
153- // r2 and r3 can reach the succ state
154- reachesEnd ( r2 , succ ) and
155- reachesEnd ( r3 , succ ) and
153+ // r2 and r3 can reach the pumpEnd state
154+ reachesEnd ( r2 , pumpEnd ) and
155+ reachesEnd ( r3 , pumpEnd ) and
156156 // The first element is either inside a repetition (or the start state itself)
157157 isRepetitionOrStart ( r1 ) and
158158 // The last element is inside a repetition
@@ -169,9 +169,9 @@ module Make<RegexTreeViewSig TreeImpl> {
169169 }
170170
171171 pragma [ noinline]
172- private predicate reachesEnd ( State s , State succ ) {
173- isStartLoops ( _, succ ) and
174- delta + ( s ) = succ
172+ private predicate reachesEnd ( State s , State pumpEnd ) {
173+ isStartLoops ( _, pumpEnd ) and
174+ delta + ( s ) = pumpEnd
175175 }
176176
177177 /**
@@ -192,15 +192,15 @@ module Make<RegexTreeViewSig TreeImpl> {
192192 }
193193
194194 /**
195- * Holds if `pivot` and `succ ` are a pair of loops that could be the beginning of a quadratic blowup.
195+ * Holds if `pivot` and `pumpEnd ` are a pair of loops that could be the beginning of a quadratic blowup.
196196 *
197- * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != succ `.
198- * The case where `pivot = succ ` causes exponential backtracking and is handled by the `js/redos` query.
197+ * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != pumpEnd `.
198+ * The case where `pivot = pumpEnd ` causes exponential backtracking and is handled by the `js/redos` query.
199199 */
200- predicate isStartLoops ( State pivot , State succ ) {
201- pivot != succ and
202- succ .getRepr ( ) instanceof InfiniteRepetitionQuantifier and
203- delta + ( pivot ) = succ and
200+ predicate isStartLoops ( State pivot , State pumpEnd ) {
201+ pivot != pumpEnd and
202+ pumpEnd .getRepr ( ) instanceof InfiniteRepetitionQuantifier and
203+ delta + ( pivot ) = pumpEnd and
204204 (
205205 pivot .getRepr ( ) instanceof InfiniteRepetitionQuantifier
206206 or
@@ -223,7 +223,7 @@ module Make<RegexTreeViewSig TreeImpl> {
223223 exists ( State r1 , State r2 , State r3 |
224224 hasCommonStep ( q , s1 , s2 , s3 , r1 , r2 , r3 ) and
225225 r =
226- MkStateTuple ( pragma [ only_bind_out ] ( q .getPivot ( ) ) , pragma [ only_bind_out ] ( q .getSucc ( ) ) ,
226+ MkStateTuple ( pragma [ only_bind_out ] ( q .getPivot ( ) ) , pragma [ only_bind_out ] ( q .getPumpEnd ( ) ) ,
227227 pragma [ only_bind_out ] ( r1 ) , pragma [ only_bind_out ] ( r2 ) , pragma [ only_bind_out ] ( r3 ) )
228228 )
229229 }
@@ -270,34 +270,34 @@ module Make<RegexTreeViewSig TreeImpl> {
270270 }
271271
272272 /** Gets a tuple reachable in a forwards exploratory search from the start state `(pivot, pivot, pivot)`. */
273- private StateTuple getReachableFromStartStateForwards ( State pivot , State succ ) {
273+ private StateTuple getReachableFromStartStateForwards ( State pivot , State pumpEnd ) {
274274 // base case.
275- isStartLoops ( pivot , succ ) and
276- result = MkStateTuple ( pivot , succ , pivot , pivot , succ )
275+ isStartLoops ( pivot , pumpEnd ) and
276+ result = MkStateTuple ( pivot , pumpEnd , pivot , pivot , pumpEnd )
277277 or
278278 // recursive case
279279 exists ( StateTuple p |
280- p = getReachableFromStartStateForwards ( pivot , succ ) and
280+ p = getReachableFromStartStateForwards ( pivot , pumpEnd ) and
281281 step ( p , _, _, _, result )
282282 )
283283 }
284284
285285 /**
286- * Gets a state tuple that can reach the end state `(succ, succ, succ )`, found via a backwards exploratory search.
287- * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pivot )`.
286+ * Gets a state tuple that can reach the end state `(pivot, pumpEnd, pumpEnd )`, found via a backwards exploratory search.
287+ * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pumpEnd )`.
288288 * The resulting tuples are exactly those that are on a path from the start state to the end state.
289289 */
290- private StateTuple getARelevantStateTuple ( State pivot , State succ ) {
290+ private StateTuple getARelevantStateTuple ( State pivot , State pumpEnd ) {
291291 // base case.
292- isStartLoops ( pivot , succ ) and
293- result = MkStateTuple ( pivot , succ , pivot , succ , succ ) and
294- result = getReachableFromStartStateForwards ( pivot , succ )
292+ isStartLoops ( pivot , pumpEnd ) and
293+ result = MkStateTuple ( pivot , pumpEnd , pivot , pumpEnd , pumpEnd ) and
294+ result = getReachableFromStartStateForwards ( pivot , pumpEnd )
295295 or
296296 // recursive case
297297 exists ( StateTuple p |
298- p = getARelevantStateTuple ( pivot , succ ) and
298+ p = getARelevantStateTuple ( pivot , pumpEnd ) and
299299 step ( result , _, _, _, p ) and
300- pragma [ only_bind_out ] ( result ) = getReachableFromStartStateForwards ( pivot , succ ) // was reachable in the forwards pass.
300+ pragma [ only_bind_out ] ( result ) = getReachableFromStartStateForwards ( pivot , pumpEnd ) // was reachable in the forwards pass.
301301 )
302302 }
303303
@@ -309,14 +309,14 @@ module Make<RegexTreeViewSig TreeImpl> {
309309 pragma [ noinline]
310310 predicate tupleDeltaBackwards ( StateTuple dst , StateTuple src ) {
311311 step ( src , _, _, _, dst ) and
312- // `step` ensures that `src` and `dst` have the same pivot and succ .
312+ // `step` ensures that `src` and `dst` have the same pivot and pumpEnd .
313313 src = getARelevantStateTuple ( _, _) and
314314 dst = getARelevantStateTuple ( _, _)
315315 }
316316
317317 /**
318318 * Holds if `tuple` is an end state in our search, and `tuple` is on a path from a start state to an end state.
319- * That means there exists a pair of loops `(pivot, succ )` such that `tuple = (pivot, succ, succ )`.
319+ * That means there exists a pair of loops `(pivot, pumpEnd )` such that `tuple = (pivot, pumpEnd, pumpEnd )`.
320320 */
321321 predicate isEndTuple ( StateTuple tuple ) {
322322 tuple = getEndTuple ( _, _) and
@@ -341,8 +341,8 @@ module Make<RegexTreeViewSig TreeImpl> {
341341 StateTuple q , InputSymbol s1 , InputSymbol s2 , InputSymbol s3 , StateTuple r
342342 ) {
343343 step ( q , s1 , s2 , s3 , r ) and
344- exists ( State pivot , State succ , StateTuple end |
345- end = MkStateTuple ( pivot , succ , pivot , succ , succ ) and
344+ exists ( State pivot , State pumpEnd , StateTuple end |
345+ end = MkStateTuple ( pivot , pumpEnd , pivot , pumpEnd , pumpEnd ) and
346346 pragma [ only_bind_out ] ( distBackFromEnd ( q , end ) ) =
347347 pragma [ only_bind_out ] ( distBackFromEnd ( r , end ) ) + 1
348348 )
@@ -385,15 +385,15 @@ module Make<RegexTreeViewSig TreeImpl> {
385385 }
386386
387387 private newtype TTrace =
388- Nil ( State pivot , State succ ) {
389- isStartLoops ( pivot , succ ) and
390- getStartTuple ( pivot , succ ) = getARelevantStateTuple ( pivot , succ )
388+ Nil ( State pivot , State pumpEnd ) {
389+ isStartLoops ( pivot , pumpEnd ) and
390+ getStartTuple ( pivot , pumpEnd ) = getARelevantStateTuple ( pivot , pumpEnd )
391391 } or
392392 Step ( TTrace prev , StateTuple nextTuple ) {
393393 exists ( StateTuple prevTuple |
394- exists ( State pivot , State succ |
395- prev = Nil ( pivot , succ ) and
396- prevTuple = getStartTuple ( pivot , succ )
394+ exists ( State pivot , State pumpEnd |
395+ prev = Nil ( pivot , pumpEnd ) and
396+ prevTuple = getStartTuple ( pivot , pumpEnd )
397397 )
398398 or
399399 prev = Step ( _, prevTuple )
@@ -404,7 +404,7 @@ module Make<RegexTreeViewSig TreeImpl> {
404404
405405 /**
406406 * A list of tuples of input symbols that describe a path in the product automaton
407- * starting from a start state `(pivot, pivot, succ )`.
407+ * starting from a start state `(pivot, pivot, pumpEnd )`.
408408 */
409409 class Trace extends TTrace {
410410 /**
@@ -419,27 +419,27 @@ module Make<RegexTreeViewSig TreeImpl> {
419419 StateTuple getTuple ( ) {
420420 this = Step ( _, result )
421421 or
422- exists ( State prev , State succ |
423- this = Nil ( prev , succ ) and
424- result = getStartTuple ( prev , succ )
422+ exists ( State prev , State pumpEnd |
423+ this = Nil ( prev , pumpEnd ) and
424+ result = getStartTuple ( prev , pumpEnd )
425425 )
426426 }
427427 }
428428
429429 /**
430- * Gets the tuple `(pivot, succ, succ )` from the product automaton.
430+ * Gets the tuple `(pivot, pumpEnd, pumpEnd )` from the product automaton.
431431 */
432- StateTuple getEndTuple ( State pivot , State succ ) {
433- isStartLoops ( pivot , succ ) and
434- result = MkStateTuple ( pivot , succ , pivot , succ , succ )
432+ StateTuple getEndTuple ( State pivot , State pumpEnd ) {
433+ isStartLoops ( pivot , pumpEnd ) and
434+ result = MkStateTuple ( pivot , pumpEnd , pivot , pumpEnd , pumpEnd )
435435 }
436436
437437 /**
438- * Gets the tuple `(pivot, pivot, succ )` from the product automaton.
438+ * Gets the tuple `(pivot, pivot, pumpEnd )` from the product automaton.
439439 */
440- StateTuple getStartTuple ( State pivot , State succ ) {
441- isStartLoops ( pivot , succ ) and
442- result = MkStateTuple ( pivot , succ , pivot , pivot , succ )
440+ StateTuple getStartTuple ( State pivot , State pumpEnd ) {
441+ isStartLoops ( pivot , pumpEnd ) and
442+ result = MkStateTuple ( pivot , pumpEnd , pivot , pivot , pumpEnd )
443443 }
444444
445445 /** An implementation of a chain containing chars for use by `Concretizer`. */
@@ -464,18 +464,18 @@ module Make<RegexTreeViewSig TreeImpl> {
464464 /**
465465 * Holds if matching repetitions of `pump` can:
466466 * 1) Transition from `pivot` back to `pivot`.
467- * 2) Transition from `pivot` to `succ `.
468- * 3) Transition from `succ ` to `succ `.
467+ * 2) Transition from `pivot` to `pumpEnd `.
468+ * 3) Transition from `pumpEnd ` to `pumpEnd `.
469469 *
470470 * From theorem 3 in the paper linked in the top of this file we can therefore conclude that
471471 * the regular expression has polynomial backtracking - if a rejecting suffix exists.
472472 *
473473 * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are
474474 * available in the `hasReDoSResult` predicate.
475475 */
476- predicate isPumpable ( State pivot , State succ , string pump ) {
476+ predicate isPumpable ( State pivot , State pumpEnd , string pump ) {
477477 exists ( StateTuple q , Trace t |
478- q = getEndTuple ( pivot , succ ) and
478+ q = getEndTuple ( pivot , pumpEnd ) and
479479 q = t .getTuple ( ) and
480480 pump = Concretizer< CharTreeImpl > :: concretize ( t )
481481 )
0 commit comments