Skip to content

Commit 0fb28f4

Browse files
committed
Sync shared files
1 parent 20f4d5a commit 0fb28f4

File tree

4 files changed

+70
-26
lines changed

4 files changed

+70
-26
lines changed

javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,17 @@ private class Trace extends TTrace {
277277
result = "Step(" + s1 + ", " + s2 + ", " + t + ")"
278278
)
279279
}
280-
}
281280

282-
/**
283-
* Gets a string corresponding to the trace `t`.
284-
*/
285-
private string concretise(Trace t) {
286-
t = Nil() and result = ""
287-
or
288-
exists(InputSymbol s1, InputSymbol s2, Trace rest | t = Step(s1, s2, rest) |
289-
result = concretise(rest) + intersect(s1, s2)
290-
)
281+
/** Holds if the `i`th pair of this trace is `(s1, s2)`. */
282+
predicate hasPair(int i, InputSymbol s1, InputSymbol s2) {
283+
this = Step(s1, s2, _) and
284+
i = 0
285+
or
286+
exists(Trace t |
287+
this = Step(_, _, t) and
288+
t.hasPair(i - 1, s1, s2)
289+
)
290+
}
291291
}
292292

293293
/**
@@ -321,14 +321,36 @@ private StatePair getAForkPair(State fork) {
321321
result = MkStatePair(epsilonPred*(fork), epsilonPred*(fork))
322322
}
323323

324+
private class RelevantTrace extends Trace {
325+
RelevantTrace() {
326+
exists(State fork, StatePair q |
327+
isReachableFromFork(fork, q, this, _) and
328+
q = getAForkPair(fork)
329+
)
330+
}
331+
332+
/** Gets a string corresponding to this trace. */
333+
// the pragma is needed for the case where `intersect(s1, s2)` has multiple values,
334+
// not for recursion
335+
language[monotonicAggregates]
336+
string concretise() {
337+
result =
338+
concat(int i, InputSymbol s1, InputSymbol s2 |
339+
this.hasPair(i, s1, s2)
340+
|
341+
intersect(s1, s2) order by i desc
342+
)
343+
}
344+
}
345+
324346
/**
325347
* Holds if `fork` is a pumpable fork with word `w`.
326348
*/
327349
private predicate isPumpable(State fork, string w) {
328-
exists(StatePair q, Trace t |
350+
exists(StatePair q, RelevantTrace t |
329351
isReachableFromFork(fork, q, t, _) and
330352
q = getAForkPair(fork) and
331-
w = concretise(t)
353+
w = t.concretise()
332354
)
333355
}
334356

javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string {
3232
}
3333

3434
/**
35-
* Holds if repeating `pump' starting at `state` is a candidate for causing backtracking.
35+
* Holds if repeating `pump` starting at `state` is a candidate for causing backtracking.
3636
* No check whether a rejected suffix exists has been made.
3737
*/
3838
private predicate isReDoSCandidate(State state, string pump) {

python/ql/lib/semmle/python/security/performance/ExponentialBackTracking.qll

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,17 @@ private class Trace extends TTrace {
277277
result = "Step(" + s1 + ", " + s2 + ", " + t + ")"
278278
)
279279
}
280-
}
281280

282-
/**
283-
* Gets a string corresponding to the trace `t`.
284-
*/
285-
private string concretise(Trace t) {
286-
t = Nil() and result = ""
287-
or
288-
exists(InputSymbol s1, InputSymbol s2, Trace rest | t = Step(s1, s2, rest) |
289-
result = concretise(rest) + intersect(s1, s2)
290-
)
281+
/** Holds if the `i`th pair of this trace is `(s1, s2)`. */
282+
predicate hasPair(int i, InputSymbol s1, InputSymbol s2) {
283+
this = Step(s1, s2, _) and
284+
i = 0
285+
or
286+
exists(Trace t |
287+
this = Step(_, _, t) and
288+
t.hasPair(i - 1, s1, s2)
289+
)
290+
}
291291
}
292292

293293
/**
@@ -321,14 +321,36 @@ private StatePair getAForkPair(State fork) {
321321
result = MkStatePair(epsilonPred*(fork), epsilonPred*(fork))
322322
}
323323

324+
private class RelevantTrace extends Trace {
325+
RelevantTrace() {
326+
exists(State fork, StatePair q |
327+
isReachableFromFork(fork, q, this, _) and
328+
q = getAForkPair(fork)
329+
)
330+
}
331+
332+
/** Gets a string corresponding to this trace. */
333+
// the pragma is needed for the case where `intersect(s1, s2)` has multiple values,
334+
// not for recursion
335+
language[monotonicAggregates]
336+
string concretise() {
337+
result =
338+
concat(int i, InputSymbol s1, InputSymbol s2 |
339+
this.hasPair(i, s1, s2)
340+
|
341+
intersect(s1, s2) order by i desc
342+
)
343+
}
344+
}
345+
324346
/**
325347
* Holds if `fork` is a pumpable fork with word `w`.
326348
*/
327349
private predicate isPumpable(State fork, string w) {
328-
exists(StatePair q, Trace t |
350+
exists(StatePair q, RelevantTrace t |
329351
isReachableFromFork(fork, q, t, _) and
330352
q = getAForkPair(fork) and
331-
w = concretise(t)
353+
w = t.concretise()
332354
)
333355
}
334356

python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string {
3232
}
3333

3434
/**
35-
* Holds if repeating `pump' starting at `state` is a candidate for causing backtracking.
35+
* Holds if repeating `pump` starting at `state` is a candidate for causing backtracking.
3636
* No check whether a rejected suffix exists has been made.
3737
*/
3838
private predicate isReDoSCandidate(State state, string pump) {

0 commit comments

Comments
 (0)