Skip to content

Commit 404cbc9

Browse files
committed
rename succ to pumpEnd throughout SuperLinearBackTracking.qll
1 parent 3f18b77 commit 404cbc9

File tree

1 file changed

+71
-71
lines changed

1 file changed

+71
-71
lines changed

shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
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

Comments
 (0)