Skip to content

Commit 5052452

Browse files
committed
SuperlinearBackTracking: Speedup concretise
1 parent 7efe698 commit 5052452

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,6 @@ class Trace extends TTrace {
254254
}
255255
}
256256

257-
/**
258-
* Gets a string corresponding to the trace `t`.
259-
*/
260-
string concretise(Trace t) {
261-
t = Nil() and result = ""
262-
or
263-
exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace rest | t = Step(s1, s2, s3, rest) |
264-
result = concretise(rest) + getAThreewayIntersect(s1, s2, s3)
265-
)
266-
}
267-
268257
/**
269258
* Holds if there exists a transition from `r` to `q` in the product automaton.
270259
* Notice that the arguments are flipped, and thus the direction is backwards.
@@ -332,6 +321,39 @@ StateTuple getAnEndTuple(State pivot, State succ) {
332321
result = MkStateTuple(pivot, succ, succ)
333322
}
334323

324+
private class RelevantTrace extends Trace {
325+
RelevantTrace() {
326+
exists(State pivot, State succ, StateTuple q |
327+
isReachableFromStartTuple(pivot, succ, q, this, _) and
328+
q = getAnEndTuple(pivot, succ)
329+
)
330+
}
331+
332+
private Trace getSuffix(int i) {
333+
i = 0 and
334+
result = this
335+
or
336+
this.getSuffix(i - 1) = Step(_, _, _, result)
337+
}
338+
339+
private predicate hasTuple(int i, InputSymbol s1, InputSymbol s2, InputSymbol s3) {
340+
this.getSuffix(i) = Step(s1, s2, s3, _)
341+
}
342+
343+
/** Gets a string corresponding to this trace. */
344+
// the pragma is needed for the case where `getAThreewayIntersect(s1, s2, s3)` has multiple values,
345+
// not for recursion
346+
language[monotonicAggregates]
347+
string concretise() {
348+
result =
349+
concat(int i, InputSymbol s1, InputSymbol s2, InputSymbol s3 |
350+
this.hasTuple(i, s1, s2, s3)
351+
|
352+
getAThreewayIntersect(s1, s2, s3) order by i desc
353+
)
354+
}
355+
}
356+
335357
/**
336358
* Holds if matching repetitions of `pump` can:
337359
* 1) Transition from `pivot` back to `pivot`.
@@ -345,10 +367,10 @@ StateTuple getAnEndTuple(State pivot, State succ) {
345367
* available in the `hasReDoSResult` predicate.
346368
*/
347369
predicate isPumpable(State pivot, State succ, string pump) {
348-
exists(StateTuple q, Trace t |
370+
exists(StateTuple q, RelevantTrace t |
349371
isReachableFromStartTuple(pivot, succ, q, t, _) and
350372
q = getAnEndTuple(pivot, succ) and
351-
pump = concretise(t)
373+
pump = t.concretise()
352374
)
353375
}
354376

0 commit comments

Comments
 (0)