diff --git a/javascript/ql/src/semmle/javascript/security/performance/ReDoSUtil.qll b/javascript/ql/src/semmle/javascript/security/performance/ReDoSUtil.qll index cc4156cd780..f345f24920f 100644 --- a/javascript/ql/src/semmle/javascript/security/performance/ReDoSUtil.qll +++ b/javascript/ql/src/semmle/javascript/security/performance/ReDoSUtil.qll @@ -561,6 +561,8 @@ predicate delta(State q1, EdgeLabel lbl, State q2) { lbl = Epsilon() and q2 = Accept(root) ) or + exists(RegExpRoot root | q1 = Match(root, 0) | lbl = Any() and q2 = q1) + or exists(RegExpDollar dollar | q1 = before(dollar) | lbl = Epsilon() and q2 = Accept(getRoot(dollar)) ) diff --git a/javascript/ql/src/semmle/javascript/security/performance/SuperlinearBackTracking.qll b/javascript/ql/src/semmle/javascript/security/performance/SuperlinearBackTracking.qll index df1eaf8f764..c43a96bd05b 100644 --- a/javascript/ql/src/semmle/javascript/security/performance/SuperlinearBackTracking.qll +++ b/javascript/ql/src/semmle/javascript/security/performance/SuperlinearBackTracking.qll @@ -6,6 +6,349 @@ import javascript import ReDoSUtil +/* + * This module implements the analysis described in the paper: + * Valentin Wustholz, Oswaldo Olivo, Marijn J. H. Heule, and Isil Dillig: + * Static Detection of DoS Vulnerabilities in + * Programs that use Regular Expressions + * (Extended Version). + * (https://arxiv.org/pdf/1701.04045.pdf) + * + * Theorem 3 from the paper describes the basic idea. + * + * The following explains the idea using variables and predicate names that are used in the implementation: + * We consider a pair of repetitions, which we will call `pivot` and `succ`. + * + * We create a product automaton of 3-tuples of states (see `StateTuple`). + * There exists a transition `(a,b,c) -> (d,e,f)` in the product automaton + * iff there exists three transitions in the NFA `a->d, b->e, c->f` where those three + * transitions all match a shared character `char`. (see `getAThreewayIntersect`) + * + * We start a search in the product automaton at `(pivot, pivot, succ)`, + * and search for a series of transitions (a `Trace`), such that we end + * at `(pivot, succ, succ)` (see `isReachableFromStartTuple`). + * + * For example, consider the regular expression `/^\d*5\w*$/`. + * The search will start at the tuple `(\d*, \d*, \w*)` and search + * for a path to `(\d*, \w*, \w*)`. + * This path exists, and consists of a single transition in the product automaton, + * where the three corresponding NFA edges all match the character `"5"`. + * + * The start-state in the NFA has an any-transition to itself, this allows us to + * flag regular expressions such as `/a*$/` - which does not have a start anchor - + * and can thus start matching anywhere. + * + * The implementation is not perfect. + * It has the same suffix detection issue as the `js/redos` query, which can cause false positives. + * It also doesn't find all transitions in the product automaton, which can cause false negatives. + */ + +/** + * An instantiaion of `ReDoSConfiguration` for superliniear ReDoS. + */ +class SuperLiniearReDoSConfiguration extends ReDoSConfiguration { + SuperLiniearReDoSConfiguration() { this = "SuperLiniearReDoSConfiguration" } + + override predicate isReDoSCandidate(State state, string pump) { isPumpable(_, state, pump) } +} + +/** + * Gets any root (start) state of a regular expression. + */ +private State getRootState() { result = Match(any(RegExpRoot r), 0) } + +/** + * A state in the product automaton. + * The product automaton contains 3-tuples of states. + * + * We lazily only construct those states that we are actually + * going to need. + * Either a start state `(pivot, pivot, succ)`, or a state + * where there exists a transition from an already existing state. + * + * The exponential variant of this query (`js/redos`) uses an optimization + * trick where `q1 <= q2`. This trick cannot be used here as the order + * of the elements matter. + */ +newtype TStateTuple = + MkStateTuple(State q1, State q2, State q3) { + // starts at (pivot, pivot, succ) + isStartLoops(q1, q3) and q1 = q2 + or + step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) + } + +class StateTuple extends TStateTuple { + State q1; + State q2; + State q3; + + StateTuple() { this = MkStateTuple(q1, q2, q3) } + + string toString() { result = "(" + q1 + ", " + q2 + ", " + q3 + ")" } + + pragma[noinline] + predicate isTuple(State r1, State r2, State r3) { r1 = q1 and r2 = q2 and r3 = q3 } +} + +/** + * A module for determining feasible tuples for the product automaton. + * + * The implementation is split into many predicates for performance reasons. + */ +private module FeasibleTuple { + /** + * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state to an end-state in the product automaton. + */ + predicate isFeasibleTuple(State r1, State r2, State r3) { + // The first element is either inside a repetition (or the start state itself) + isRepeitionOrStart(r1) and + // The last element is inside a repetition + stateInsideRepetition(r3) and + // The states are reachable in the NFA in the order r1 -> r2 -> r3 + delta+(r1) = r2 and + delta+(r2) = r3 and + // The last element can reach a target (the "succ" state in a `(pivot, succ)` pair). + canReachATarget(r3) and + // The first element can reach a beginning (the "pivot" state in a `(pivot, succ)` pair). + canReachABeginning(r1) + } + + /** + * Holds if `s` is either inside a repetition, or is the start state (which is a repetition). + */ + pragma[noinline] + private predicate isRepeitionOrStart(State s) { stateInsideRepetition(s) or s = getRootState() } + + /** + * Holds if state `s` might be inside a backtracking repetition. + */ + pragma[noinline] + private predicate stateInsideRepetition(State s) { + s.getRepr().getParent*() instanceof InfiniteRepetitionQuantifier + } + + /** + * Holds if there exists a path in the NFA from `s` to a "pivot" state + * (from a `(pivot, succ)` pair that starts the search). + */ + pragma[noinline] + private predicate canReachABeginning(State s) { + delta+(s) = any(State pivot | isStartLoops(pivot, _)) + } + + /** + * Holds if there exists a path in the NFA from `s` to a "succ" state + * (from a `(pivot, succ)` pair that starts the search). + */ + pragma[noinline] + private predicate canReachATarget(State s) { delta+(s) = any(State succ | isStartLoops(_, succ)) } +} + +/** + * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. + * + * There is a slight implementation difference compared to the paper: this predicate require that `pivot != succ`. + * The case where `pivot = succ` causes exponential backtracking and is handled by the `js/redos` query. + */ +predicate isStartLoops(State pivot, State succ) { + pivot != succ and + succ.getRepr() instanceof InfiniteRepetitionQuantifier and + delta+(pivot) = succ and + ( + pivot.getRepr() = any(InfiniteRepetitionQuantifier i) + or + pivot = Match(any(RegExpRoot root), 0) + ) +} + +/** + * Gets a state for which there exists a transition in the NFA from `s'. + */ +State delta(State s) { delta(s, _, result) } + +/** + * Holds if there are transitions from the components of `q` to the corresponding + * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. + */ +pragma[noinline] +predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { + exists(State r1, State r2, State r3 | + step(q, s1, s2, s3, r1, r2, r3) and r = MkStateTuple(r1, r2, r3) + ) +} + +/** + * Holds if there are transitions from the components of `q` to `r1`, `r2`, and `r3 + * labelled with `s1`, `s2`, and `s3`, respectively. + */ +pragma[noopt] +predicate step( + StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, State r1, State r2, State r3 +) { + exists(State q1, State q2, State q3 | q.isTuple(q1, q2, q3) | + deltaClosed(q1, s1, r1) and + deltaClosed(q2, s2, r2) and + deltaClosed(q3, s3, r3) and + // use noopt to force the join on `getAThreewayIntersect` to happen last. + exists(getAThreewayIntersect(s1, s2, s3)) + ) +} + +/** + * Gets a char that is matched by all the edges `s1`, `s2`, and `s3`. + * + * The result is not complete, and might miss some combination of edges that share some character. + */ +pragma[noinline] +string getAThreewayIntersect(InputSymbol s1, InputSymbol s2, InputSymbol s3) { + result = intersect(s1, s2) and result = [intersect(s2, s3), intersect(s1, s3)] + or + result = intersect(s1, s3) and result = [intersect(s2, s3), intersect(s1, s2)] + or + result = intersect(s2, s3) and result = [intersect(s1, s2), intersect(s1, s3)] +} + +private newtype TTrace = + Nil() or + Step(InputSymbol s1, InputSymbol s2, InputSymbol s3, TTrace t) { + exists(StateTuple p | + isReachableFromStartTuple(_, _, p, t, _) and + step(p, s1, s2, s3, _) + ) + or + exists(State pivot, State succ | isStartLoops(pivot, succ) | + t = Nil() and step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, _) + ) + } + +/** + * A list of tuples of input symbols that describe a path in the product automaton + * starting from some start state. + */ +class Trace extends TTrace { + string toString() { + this = Nil() and result = "Nil()" + or + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace t | this = Step(s1, s2, s3, t) | + result = "Step(" + s1 + ", " + s2 + ", " + s3 + ", " + t + ")" + ) + } +} + +/** + * Gets a string corresponding to the trace `t`. + */ +string concretise(Trace t) { + t = Nil() and result = "" + or + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, Trace rest | t = Step(s1, s2, s3, rest) | + result = concretise(rest) + getAThreewayIntersect(s1, s2, s3) + ) +} + +/** + * Holds if there exists a transition from `r` to `q` in the product automaton. + * Notice that the arguments are flipped, and thus the direction is backwards. + */ +pragma[noinline] +predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { step(r, _, _, _, q) } + +/** + * Holds if `tuple` is an end state in our search. + * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. + */ +predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } + +/** + * Gets the minimum length of a path from `r` to some an end state `end`. + * + * The implementation searches backwards from the end-tuple. + * This approach was chosen because it is way more efficient if the first predicate given to `shortestDistances` is small. + * The `end` argument must always be an end state. + */ +int distBackFromEnd(StateTuple r, StateTuple end) = + shortestDistances(isEndTuple/1, tupleDeltaBackwards/2)(end, r, result) + +/** + * Holds if there exists a pair of repetitions `(pivot, succ)` in the regular expression such that: + * `tuple` is reachable from `(pivot, pivot, succ)` in the product automaton, + * and there is a distance of `dist` from `tuple` to the nearest end-tuple `(pivot, succ, succ)`, + * and a path from a start-state to `tuple` follows the transitions in `trace`. + */ +predicate isReachableFromStartTuple(State pivot, State succ, StateTuple tuple, Trace trace, int dist) { + // base case. The first step is inlined to start the search after all possible 1-steps, and not just the ones with the shortest path. + exists(InputSymbol s1, InputSymbol s2, InputSymbol s3, State q1, State q2, State q3 | + isStartLoops(pivot, succ) and + step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and + tuple = MkStateTuple(q1, q2, q3) and + trace = Step(s1, s2, s3, Nil()) and + dist = distBackFromEnd(tuple, MkStateTuple(pivot, succ, succ)) + ) + or + // recursive case + exists(StateTuple p, Trace v, InputSymbol s1, InputSymbol s2, InputSymbol s3 | + isReachableFromStartTuple(pivot, succ, p, v, dist + 1) and + dist = isReachableFromStartTupleHelper(pivot, succ, tuple, p, s1, s2, s3) and + trace = Step(s1, s2, s3, v) + ) +} + +/** + * Helper predicate for the recursive case in `isReachableFromStartTuple`. + */ +pragma[noinline] +private int isReachableFromStartTupleHelper( + State pivot, State succ, StateTuple r, StateTuple p, InputSymbol s1, InputSymbol s2, + InputSymbol s3 +) { + result = distBackFromEnd(r, MkStateTuple(pivot, succ, succ)) and + step(p, s1, s2, s3, r) +} + +/** + * Gets the tuple `(pivot, succ, succ)` from the product automaton. + */ +StateTuple getAnEndTuple(State pivot, State succ) { + isStartLoops(pivot, succ) and + result = MkStateTuple(pivot, succ, succ) +} + +/** + * Holds if matching repetitions of `pump` can: + * 1) Transition from `pivot` back to `pivot`. + * 2) Transition from `pivot` to `succ`. + * 3) Transition from `succ` to `succ`. + * + * From theorem 3 in the paper linked in the top of this file we can therefore conclude that + * the regular expression has polynomial backtracking - if a rejecting suffix exists. + * + * This predicate is used by `SuperLiniearReDoSConfiguration`, and the final results are + * available in the `hasReDoSResult` predicate. + */ +predicate isPumpable(State pivot, State succ, string pump) { + exists(StateTuple q, Trace t | + isReachableFromStartTuple(pivot, succ, q, t, _) and + q = getAnEndTuple(pivot, succ) and + pump = concretise(t) + ) +} + +/** + * Holds if repetitions of `pump` at `t` will cause polynomial backtracking. + */ +predicate polynimalReDoS(RegExpTerm t, string msg) { + exists(string pump, State s, string prefixMsg | + hasReDoSResult(t, pump, s, prefixMsg) and + exists(State pivot | + isPumpable(pivot, s, _) and + msg = + "Strings " + prefixMsg + "with many repetitions of '" + pump + + "' can start matching anywhere after the start of the preceeding " + pivot.getRepr() + ) + ) +} + /** * Holds if `t` matches at least an epsilon symbol. * @@ -35,68 +378,6 @@ private predicate matchesEpsilon(RegExpTerm t) { forex(RegExpTerm child | child = t.(RegExpSequence).getAChild() | matchesEpsilon(child)) } -/** - * Gets a term that matches the symbol immediately before `t` is done matching. - * - * Examples: - * - * - For `d` in `abc?de` this gets `b`, `c`, `c?` (in addition to `d`). - * - For `(bc|de)` in `a(bc|de)f` this gets `c` and `e` (in addition to `bc|de` and `(bc|de)`). - */ -private RegExpTerm getAMatchPredecessor(RegExpTerm t) { - result = t - or - exists(RegExpTerm recurse | result = getAMatchPredecessor(recurse) | - // wrappers depend on their children - recurse = t.getAChild() and - ( - t instanceof RegExpAlt - or - t instanceof RegExpGroup - or - t instanceof RegExpQuantifier - ) - or - recurse = t.(RegExpSequence).getLastChild() - or - recurse = t.(RegExpBackRef).getGroup() - or - // recurse past epsilon terms - matchesEpsilon(t) and recurse = t.getPredecessor() - ) -} - -private RegExpCharacterClassEscape unwrapCharacterClassEscape(RegExpTerm t) { - t = result or - t.(RegExpCharacterClass).getAChild() = result -} - -pragma[inline] -private predicate compatibleConstants(RegExpTerm t1, RegExpTerm t2) { - exists(string s1, string s2 | - s1 = t1.getAMatchedString() and s2 = t2.getAMatchedString() - or - unwrapCharacterClassEscape(t1).getValue() = s1 and - unwrapCharacterClassEscape(t2).getValue() = s2 - | - s1 = s2 - ) -} - -/** - * Holds if `s1` and `s2` possibly have a non-empty intersection. - * - * This is a simple, and under-approximate, version of - * ReDoS::compatible/2, as this predicate only handles some character - * classes and constant values. - */ -pragma[inline] -private predicate compatible(RegExpTerm s1, RegExpTerm s2) { - not s1.(RegExpCharacterClass).isInverted() and - not s2.(RegExpCharacterClass).isInverted() and - compatibleConstants(s1, s2) -} - /** * A term that may cause a regular expression engine to perform a * polynomial number of match attempts, relative to the input length. @@ -105,33 +386,9 @@ class PolynomialBackTrackingTerm extends InfiniteRepetitionQuantifier { string reason; PolynomialBackTrackingTerm() { - // the regexp may fail to match ... - exists(RegExpTerm succ | this.getSuccessor+() = succ | not matchesEpsilon(succ)) and - ( - // ... and while failing, it will try to start matching at all positions of a long string - forall(RegExpTerm pred | pred = this.getPredecessor+() | matchesEpsilon(pred)) and - reason = "it can start matching anywhere" - or - exists(RegExpTerm pred | - pred instanceof InfiniteRepetitionQuantifier - or - forall(RegExpTerm predpred | predpred = pred.getPredecessor+() | matchesEpsilon(predpred)) - | - pred = getAMatchPredecessor(this.getPredecessor()) and - ( - // compatible children - compatible(pred.getAChild(), this.getAChild()) - or - // or `this` is compatible with everything (and the predecessor is something) - unique( | | this.getAChild()) instanceof RegExpDot and - exists([pred, pred.getAChild()].getAMatchedString()) - ) and - reason = - "it can start matching anywhere after the start of the preceeding '" + pred.toString() + - "'" - ) - ) and - not this.getParent*() instanceof RegExpSubPattern // too many corner cases + polynimalReDoS(this, _) and + // there might be many reasons for this term to have polynomial backtracking - we pick an arbitary one. + reason = min(string msg | polynimalReDoS(this, msg)) } /** diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected index 6d52e525d6c..7d8945d761e 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected @@ -1,306 +1,454 @@ -| polynomial-redos.js:7:24:7:26 | \\s+ | it can start matching anywhere | -| polynomial-redos.js:8:17:8:18 | * | it can start matching anywhere | -| polynomial-redos.js:9:19:9:21 | \\s* | it can start matching anywhere | -| polynomial-redos.js:11:19:11:20 | .* | it can start matching anywhere | -| polynomial-redos.js:12:19:12:20 | .* | it can start matching anywhere | -| polynomial-redos.js:15:28:15:35 | [\\s\\S]*? | it can start matching anywhere after the start of the preceeding '\\s*' | -| polynomial-redos.js:18:17:18:22 | [0-9]* | it can start matching anywhere | -| polynomial-redos.js:18:83:18:100 | [\\u0600-\\u06FF\\/]+ | it can start matching anywhere | -| polynomial-redos.js:19:17:19:22 | [0-9]* | it can start matching anywhere | -| polynomial-redos.js:20:56:20:58 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d*' | -| polynomial-redos.js:20:56:20:58 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d+' | -| polynomial-redos.js:22:57:22:59 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d*' | -| polynomial-redos.js:22:57:22:59 | \\d+ | it can start matching anywhere after the start of the preceeding '\\d+' | -| polynomial-redos.js:25:37:25:56 | [a-zA-Z0-9+\\/ \\t\\n]+ | it can start matching anywhere after the start of the preceeding '[ \\t]+' | -| polynomial-redos.js:25:63:25:64 | .* | it can start matching anywhere after the start of the preceeding '[=]*' | -| polynomial-redos.js:25:63:25:64 | .* | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9+\\/ \\t\\n]+' | -| polynomial-redos.js:27:14:27:22 | [A-Z]{2,} | it can start matching anywhere | -| polynomial-redos.js:30:19:30:22 | [?]+ | it can start matching anywhere | -| polynomial-redos.js:30:23:30:24 | .* | it can start matching anywhere after the start of the preceeding '[?]' | -| polynomial-redos.js:30:23:30:24 | .* | it can start matching anywhere after the start of the preceeding '[?]+' | -| polynomial-redos.js:31:42:31:43 | -+ | it can start matching anywhere | -| polynomial-redos.js:32:45:32:47 | \\n* | it can start matching anywhere | -| polynomial-redos.js:33:17:33:20 | (.)* | it can start matching anywhere | -| polynomial-redos.js:36:18:36:19 | .* | it can start matching anywhere after the start of the preceeding '<' | -| polynomial-redos.js:37:18:37:19 | .* | it can start matching anywhere after the start of the preceeding '<' | -| polynomial-redos.js:38:18:38:19 | .* | it can start matching anywhere after the start of the preceeding '<' | -| polynomial-redos.js:48:22:48:24 | \\s* | it can start matching anywhere | -| polynomial-redos.js:50:4:50:5 | .* | it can start matching anywhere after the start of the preceeding 'Y' | -| polynomial-redos.js:51:11:51:17 | (YH\|J)* | it can start matching anywhere after the start of the preceeding '(YH\|K)' | -| polynomial-redos.js:51:11:51:17 | (YH\|J)* | it can start matching anywhere after the start of the preceeding 'YH\|K' | -| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding '(YH\|K)' | -| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'K' | -| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'YH' | -| polynomial-redos.js:52:12:52:13 | .* | it can start matching anywhere after the start of the preceeding 'YH\|K' | -| polynomial-redos.js:53:3:53:8 | (B\|Y)+ | it can start matching anywhere | -| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)' | -| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' | -| polynomial-redos.js:53:9:53:12 | (Y)* | it can start matching anywhere after the start of the preceeding 'B\|Y' | -| polynomial-redos.js:54:4:54:9 | (B\|Y)+ | it can start matching anywhere | -| polynomial-redos.js:55:11:55:14 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' | -| polynomial-redos.js:56:10:56:13 | (Y)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' | -| polynomial-redos.js:57:11:57:16 | (Y\|K)* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' | -| polynomial-redos.js:58:11:58:12 | .* | it can start matching anywhere after the start of the preceeding '(B\|Y)+' | -| polynomial-redos.js:62:7:62:8 | Y* | it can start matching anywhere after the start of the preceeding 'Y*' | -| polynomial-redos.js:63:11:63:12 | Y* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' | -| polynomial-redos.js:64:14:64:15 | Y* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' | -| polynomial-redos.js:65:14:65:15 | .* | it can start matching anywhere after the start of the preceeding '(K\|Y)+' | -| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding '(K\|Y)' | -| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'K' | -| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'K\|Y' | -| polynomial-redos.js:66:9:66:10 | .* | it can start matching anywhere after the start of the preceeding 'Y' | -| polynomial-redos.js:67:8:67:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' | -| polynomial-redos.js:68:8:68:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' | -| polynomial-redos.js:69:8:69:9 | .* | it can start matching anywhere after the start of the preceeding '[^Y]' | -| polynomial-redos.js:75:18:75:19 | .* | it can start matching anywhere after the start of the preceeding '<' | -| polynomial-redos.js:77:18:77:19 | .* | it can start matching anywhere after the start of the preceeding 'Y' | -| polynomial-redos.js:78:25:78:31 | (YH\|J)* | it can start matching anywhere after the start of the preceeding '(YH\|K)' | -| polynomial-redos.js:78:25:78:31 | (YH\|J)* | it can start matching anywhere after the start of the preceeding 'YH\|K' | -| polynomial-redos.js:80:17:80:18 | a* | it can start matching anywhere | -| polynomial-redos.js:89:20:89:21 | a* | it can start matching anywhere after the start of the preceeding 'a*' | -| polynomial-redos.js:101:17:101:18 | a+ | it can start matching anywhere | -| polynomial-redos.js:102:20:102:21 | a+ | it can start matching anywhere after the start of the preceeding 'a+' | -| polynomial-redos.js:104:17:104:18 | a+ | it can start matching anywhere | -| polynomial-redos.js:105:17:105:18 | a+ | it can start matching anywhere | -| polynomial-redos.js:105:19:105:20 | a+ | it can start matching anywhere after the start of the preceeding 'a+' | -| polynomial-redos.js:105:21:105:22 | a+ | it can start matching anywhere after the start of the preceeding 'a+' | -| polynomial-redos.js:111:17:111:19 | \\s* | it can start matching anywhere | -| polynomial-redos.js:112:17:112:19 | \\s+ | it can start matching anywhere | -| regexplib/address.js:18:26:18:31 | [ \\w]* | it can start matching anywhere after the start of the preceeding '[ \\w]{3,}' | -| regexplib/address.js:20:144:20:147 | [ ]+ | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9 \\-.]{6,}' | -| regexplib/address.js:24:26:24:31 | [ \\w]* | it can start matching anywhere after the start of the preceeding '[ \\w]{3,}' | -| regexplib/address.js:27:3:27:5 | \\s* | it can start matching anywhere | -| regexplib/address.js:27:48:27:50 | \\s* | it can start matching anywhere | -| regexplib/address.js:27:93:27:95 | \\s* | it can start matching anywhere | -| regexplib/address.js:38:39:38:45 | [ 0-9]* | it can start matching anywhere after the start of the preceeding '[ \|\\.]*' | -| regexplib/address.js:51:235:51:239 | \\x20* | it can start matching anywhere after the start of the preceeding '\\x20*' | -| regexplib/address.js:51:631:51:635 | \\x20* | it can start matching anywhere after the start of the preceeding '\\x20*' | -| regexplib/address.js:51:796:51:798 | \\s+ | it can start matching anywhere after the start of the preceeding '\\s+' | -| regexplib/address.js:67:379:67:755 | [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\' ]+ | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\']+' | -| regexplib/address.js:69:3:69:5 | \\s* | it can start matching anywhere | -| regexplib/address.js:69:48:69:50 | \\s* | it can start matching anywhere | -| regexplib/address.js:69:93:69:95 | \\s* | it can start matching anywhere | -| regexplib/address.js:75:235:75:239 | \\x20* | it can start matching anywhere after the start of the preceeding '\\x20*' | -| regexplib/address.js:75:631:75:635 | \\x20* | it can start matching anywhere after the start of the preceeding '\\x20*' | -| regexplib/address.js:75:796:75:798 | \\s+ | it can start matching anywhere after the start of the preceeding '\\s+' | -| regexplib/address.js:85:15:85:49 | ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | it can start matching anywhere | -| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])' | -| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+' | -| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,]' | -| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[ ]' | -| regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | it can start matching anywhere after the start of the preceeding '[-]' | -| regexplib/address.js:93:3:93:5 | \\s* | it can start matching anywhere | -| regexplib/address.js:93:48:93:50 | \\s* | it can start matching anywhere | -| regexplib/address.js:93:93:93:95 | \\s* | it can start matching anywhere | -| regexplib/address.js:95:379:95:755 | [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\' ]+ | it can start matching anywhere after the start of the preceeding '[a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\']+' | -| regexplib/email.js:8:16:8:49 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | it can start matching anywhere | -| regexplib/email.js:12:2:12:4 | \\w+ | it can start matching anywhere | -| regexplib/email.js:15:6:15:13 | [\\w-\\.]* | it can start matching anywhere after the start of the preceeding '\\w+' | -| regexplib/email.js:15:28:15:30 | \\w* | it can start matching anywhere after the start of the preceeding '\\w+' | -| regexplib/email.js:20:3:20:6 | \\w+? | it can start matching anywhere | -| regexplib/email.js:28:2:28:4 | \\w+ | it can start matching anywhere | -| regexplib/email.js:28:5:28:12 | [\\w-\\.]* | it can start matching anywhere after the start of the preceeding '\\w+' | -| regexplib/email.js:28:27:28:29 | \\w* | it can start matching anywhere after the start of the preceeding '\\w+' | -| regexplib/email.js:28:73:28:87 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere | -| regexplib/email.js:28:125:28:139 | [0-9a-zA-Z'\\.]+ | it can start matching anywhere | -| regexplib/email.js:29:2:29:7 | [\\w-]+ | it can start matching anywhere | -| regexplib/markup.js:1:11:1:12 | .* | it can start matching anywhere after the start of the preceeding '<' | -| regexplib/markup.js:6:99:6:113 | [\\s\\w\\d\\)\\(\\,]* | it can start matching anywhere after the start of the preceeding '[\\d\\w]+' | -| regexplib/markup.js:11:6:11:8 | .*? | it can start matching anywhere after the start of the preceeding ' | +| regexplib/markup.js:12:40:12:42 | .*? | Strings starting with ') | +| regexplib/markup.js:12:117:12:121 | [^>]* | Strings starting with ']*>) | +| regexplib/markup.js:12:149:12:153 | [^>]* | Strings starting with 'font-family:' and with many repetitions of 'font-family:' can start matching anywhere after the start of the preceeding (font-family:[^>]*[;']) | +| regexplib/markup.js:12:171:12:175 | [^>]* | Strings starting with 'font-size:' and with many repetitions of 'font-size:' can start matching anywhere after the start of the preceeding (font-size:[^>]*[;'])(?-s) | +| regexplib/markup.js:13:6:13:12 | [^"']+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding (?:[^"']+?\|.+?(?:"\|').*?(?:"\|')?.*?)*? | +| regexplib/markup.js:13:14:13:16 | .+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding (?:[^"']+?\|.+?(?:"\|').*?(?:"\|')?.*?)*? | +| regexplib/markup.js:14:13:14:14 | .* | Strings starting with '<' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding .* | +| regexplib/markup.js:14:24:14:25 | .* | Strings starting with '<>' and with many repetitions of '>a' can start matching anywhere after the start of the preceeding .* | +| regexplib/markup.js:16:5:16:9 | [^>]* | Strings starting with 'src' and with many repetitions of 'src' can start matching anywhere after the start of the preceeding src[^>]*[^/].(?:jpg\|bmp\|gif)(?:\\"\|\\') | +| regexplib/markup.js:17:8:17:24 | (\\s(\\w*=".*?")?)* | Strings starting with '' and with many repetitions of '">' can start matching anywhere after the start of the preceeding (\\s(\\w*=".*?")?)* | +| regexplib/markup.js:19:2:19:12 | ([^'("\|')]*)("\|')){1}\|content\\s*=\\s*("\|')(?[^'("\|')]*)("\|')\|scheme\\s*=\\s*("\|')(?[^'("\|')]*)("\|')) | +| regexplib/markup.js:19:8:19:10 | \\s+ | Strings starting with '[^'("\|')]*)("\|')){1}\|content\\s*=\\s*("\|')(?[^'("\|')]*)("\|')\|scheme\\s*=\\s*("\|')(?[^'("\|')]*)("\|')) | +| regexplib/markup.js:20:52:20:53 | .* | Strings with many repetitions of '=color' can start matching anywhere after the start of the preceeding [^>]+ | +| regexplib/markup.js:20:155:20:156 | '+ | Strings with many repetitions of '''' can start matching anywhere after the start of the preceeding '+ | +| regexplib/markup.js:20:197:20:198 | "+ | Strings with many repetitions of '""' can start matching anywhere after the start of the preceeding "+ | +| regexplib/markup.js:20:245:20:247 | .*? | Strings with many repetitions of 'color: # IF found THEN move ahead "" # single or double # or no quotes\\t' can start matching anywhere after the start of the preceeding .*? | +| regexplib/markup.js:20:274:20:276 | .*? | Strings starting with ']+color.*>) #IF\\/THEN lookahead color in tag (.*?color\\s*?[=\|:]\\s*?) # IF found THEN move ahead ('+\\#*?[\\w\\s]*'+ # CAPTURE ColorName\\/Hex \|"+\\#*?[\\w\\s]*"+ # single or double \|\\#*\\w*\\b) # or no quotes\t.*?> # & move to end of tag \|.*?> # ELSE move to end of Tag ) # Close the If\\/Then lookahead # Use Multiline and IgnoreCase # Replace the matches from RE with MatchEvaluator below: # if m.Groups(1).Value<>"" then # Return "" # else # Return "" # end if | +| regexplib/markup.js:25:11:25:15 | [^>]* | Strings starting with ']*\\son\\w+=(\\w+\|'[^']*'\|"[^"]*")[^>]*> | +| regexplib/markup.js:25:45:25:49 | [^>]* | Strings starting with ']* | +| regexplib/markup.js:27:3:27:7 | [^>]* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | +| regexplib/markup.js:27:34:27:38 | [^>]* | Strings starting with ']*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | +| regexplib/markup.js:29:6:29:13 | [\\d\\D]*? | Strings starting with '/*' and with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding \\/\\*[\\d\\D]*?\\*\\/ | +| regexplib/markup.js:33:10:33:11 | .* | Strings starting with '?s/*' and with many repetitions of '?s/*' can start matching anywhere after the start of the preceeding (?s)\\/\\*.*\\*\\/ | +| regexplib/markup.js:34:4:34:10 | [^\\s>]* | Strings starting with '<' and with many repetitions of ']*)(\\s[^<]*)> | +| regexplib/markup.js:37:15:37:19 | [\\w]* | Strings starting with '[a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-zA-Z0-9\|:\|\\/\|=\|-\|.\|\\?\|&]* | +| regexplib/markup.js:40:23:40:25 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (\\/?(?\\w+))+ | +| regexplib/markup.js:40:59:40:61 | \\s* | Strings starting with 'a[' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s* | +| regexplib/markup.js:43:11:43:15 | [^>]* | Strings starting with ']*\\son\\w+=(\\w+\|'[^']*'\|"[^"]*")[^>]*> | +| regexplib/markup.js:43:45:43:49 | [^>]* | Strings starting with ']* | +| regexplib/markup.js:44:3:44:7 | [^>]* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | +| regexplib/markup.js:44:34:44:38 | [^>]* | Strings starting with ']*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | +| regexplib/markup.js:45:6:45:13 | [\\d\\D]*? | Strings starting with '/*' and with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding \\/\\*[\\d\\D]*?\\*\\/ | +| regexplib/markup.js:48:6:48:13 | [\\s\\S]*? | Strings starting with ' | +| regexplib/markup.js:53:15:53:19 | [\\w]* | Strings starting with '[a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-zA-Z0-9\|:\|\\/\|=\|-\|.\|\\?\|&]* | +| regexplib/markup.js:56:23:56:25 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (\\/?(?\\w+))+ | +| regexplib/markup.js:56:59:56:61 | \\s* | Strings starting with 'a[' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s* | +| regexplib/markup.js:61:74:61:79 | [0-9]+ | Strings starting with '' and with many repetitions of '' can start matching anywhere after the start of the preceeding [^']*? | +| regexplib/markup.js:62:9:62:14 | [^>]*? | Strings starting with ']*?href[\\s]?=[\\s\\"\\']+(.*?)[\\"\\']+.*?>([^<]+\|.*?)?<\\/a> | +| regexplib/markup.js:62:39:62:45 | [\\"\\']+ | Strings starting with '' and with many repetitions of '>;' can start matching anywhere after the start of the preceeding .*? | +| regexplib/markup.js:62:57:62:59 | .*? | Strings starting with '' and with many repetitions of '>a' can start matching anywhere after the start of the preceeding .*? | +| regexplib/markup.js:63:70:63:77 | [\\w\\W]*? | Strings with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding (?((?m:^[\\t ]*\\/{2}[^\\n\\r\\v\\f]+[\\n\\r\\v\\f]*){2,})\|(\\/\\*[\\w\\W]*?\\*\\/)) | +| regexplib/misc.js:4:36:4:44 | [a-zA-Z]* | Strings starting with 'A' and with many repetitions of 'AA' can start matching anywhere after the start of the preceeding [a-zA-Z]+ | +| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'AUX' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | +| regexplib/misc.js:81:31:81:45 | [^a-z\\:\\,\\(\\)]* | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding ([A-Zäöü0-9\\/][^a-z\\:\\,\\(\\)]*[A-Zäöü0-9])($\|[\\.\\:\\,\\;\\)\\-\\ \\+]\|s\\b) | +| regexplib/misc.js:83:18:83:23 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | +| regexplib/misc.js:83:24:83:26 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-9]+ | +| regexplib/misc.js:83:36:83:38 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-9]+ | +| regexplib/misc.js:83:72:83:77 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | +| regexplib/misc.js:83:78:83:80 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-9]+ | +| regexplib/misc.js:83:90:83:92 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-9]+ | +| regexplib/misc.js:90:4:90:11 | ([a-z])+ | Strings with many repetitions of 'aa' can start matching anywhere after the start of the preceeding (([a-z])+.)+ | +| regexplib/misc.js:93:3:93:4 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (.*\\.([wW][mM][aA])\|([mM][pP][3])$) | +| regexplib/misc.js:95:25:95:26 | .+ | Strings starting with 'at ' and with many repetitions of 'at a' can start matching anywhere after the start of the preceeding (at\\s)(?.+)(\\.)(?[^\\.]*)(\\()(?[^\\)]*)(\\))((\\sin\\s)(?.+)(:line )(?[\\d]*))? | +| regexplib/misc.js:95:71:95:76 | [^\\)]* | Strings starting with 'at a.(' and with many repetitions of '((' can start matching anywhere after the start of the preceeding (at\\s)(?.+)(\\.)(?[^\\.]*)(\\()(?[^\\)]*)(\\))((\\sin\\s)(?.+)(:line )(?[\\d]*))? | +| regexplib/misc.js:95:103:95:104 | .+ | Strings starting with 'at a.() in ' and with many repetitions of '() in -' can start matching anywhere after the start of the preceeding (at\\s)(?.+)(\\.)(?[^\\.]*)(\\()(?[^\\)]*)(\\))((\\sin\\s)(?.+)(:line )(?[\\d]*))? | +| regexplib/misc.js:101:52:101:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:112:3:112:5 | \\s* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?\\s*\\d{6}\\s*) | +| regexplib/misc.js:112:32:112:34 | \\s* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?\\s*\\d{3}\\s*\\d{4}\\s*) | +| regexplib/misc.js:114:6:114:8 | \\\|+ | Strings starting with 'a' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .+ | +| regexplib/misc.js:116:3:116:4 | .* | Strings starting with '{' and with many repetitions of '{' can start matching anywhere after the start of the preceeding {.*} | +| regexplib/misc.js:117:25:117:26 | .+ | Strings starting with '{a}' and with many repetitions of 'a)' can start matching anywhere after the start of the preceeding .+ | +| regexplib/misc.js:119:20:119:22 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (NOT)?(\\s*\\(*)\\s*(\\w+)\\s*(=\|<>\|<\|>\|LIKE\|IN)\\s*(\\(([^\\)]*)\\)\|'([^']*)'\|(-?\\d*\\.?\\d+))(\\s*\\)*\\s*)(AND\|OR)? | +| regexplib/misc.js:123:36:123:38 | .*? | Strings starting with '?se[A' and with many repetitions of '?se[Aa' can start matching anywhere after the start of the preceeding (?s)(?:\\e\\[(?:(\\d+);?)*([A-Za-z])(.*?))(?=\\e\\[\|\\z) | +| regexplib/misc.js:126:15:126:20 | [a-z]+ | Strings starting with 'a' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding [a-z]+ | +| regexplib/misc.js:141:15:141:19 | [^;]+ | Strings starting with '{\\\\f\\\\' and with many repetitions of '{\\\\f\\\\:' can start matching anywhere after the start of the preceeding (\\{\\\\f\\d*)\\\\([^;]+;) | +| regexplib/misc.js:144:52:144:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:148:12:148:18 | [^\\s>]+ | Strings starting with '<' and with many repetitions of ']+(\\s+[^"'=]+(=("[^"]*")\|('[^\\']*')\|([^\\s"'>]*))?)*\\s*\\/?> | +| regexplib/misc.js:148:20:148:22 | \\s+ | Strings starting with ']* | +| regexplib/misc.js:148:34:148:38 | [^"]* | Strings starting with ']+(\\s+[^"'=]+(=("[^"]*")\|('[^\\']*')\|([^\\s"'>]*))?)*\\s*\\/?> | +| regexplib/misc.js:148:44:148:49 | [^\\']* | Strings starting with ']+(\\s+[^"'=]+(=("[^"]*")\|('[^\\']*')\|([^\\s"'>]*))?)*\\s*\\/?> | +| regexplib/misc.js:148:68:148:70 | \\s* | Strings starting with '[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w*\|[A-Z]?\\.?)\\s?(?[A-Z]\\w*\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:14:61:14:63 | \\w* | Strings starting with 'AA' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w*\|[A-Z]?\\.?)\\s?(?[A-Z]\\w*\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:14:107:14:109 | \\w* | Strings starting with 'AAA' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w*\|[A-Z]?\\.?)\\s?(?[A-Z]\\w*\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:19:31:19:57 | [a-zæøå0-9]+ | Strings starting with '#@' and with many repetitions of '##' can start matching anywhere after the start of the preceeding ([a-zæøå0-9]+([\\.-]{0,1}[a-zæøå0-9]+\|[a-zæøå0-9]?))+ | +| regexplib/strings.js:20:3:20:20 | ((\\\\")\|[^"(\\\\")])+ | Strings starting with '"' and with many repetitions of '\\\\"' can start matching anywhere after the start of the preceeding "((\\\\")\|[^"(\\\\")])+" | +| regexplib/strings.js:21:3:21:7 | [^>]+ | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]+> | +| regexplib/strings.js:23:3:23:20 | ((\\\\")\|[^"(\\\\")])+ | Strings starting with '"' and with many repetitions of '\\\\"' can start matching anywhere after the start of the preceeding "((\\\\")\|[^"(\\\\")])+" | +| regexplib/strings.js:26:6:26:17 | [a-zA-Z,\\s]+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s* | +| regexplib/strings.js:26:18:26:20 | \\s* | Strings starting with '\\t' and with many repetitions of '\\t' can start matching anywhere after the start of the preceeding [a-zA-Z,\\s]+ | +| regexplib/strings.js:29:2:29:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*\\$AVE | +| regexplib/strings.js:30:2:30:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*[Pp]re[Ss\\$]cr[iI1]pt.* | +| regexplib/strings.js:32:35:32:37 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w+\|[A-Z]?\\.?)\\s(?[A-Z]?\\w{0,3}[A-Z]\\w+\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:32:61:32:63 | \\w+ | Strings starting with 'AA' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w+\|[A-Z]?\\.?)\\s(?[A-Z]?\\w{0,3}[A-Z]\\w+\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:32:119:32:121 | \\w* | Strings with many repetitions of 'aA' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/strings.js:40:3:40:5 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (\\w+)\\s+\\1 | +| regexplib/strings.js:48:3:48:12 | [^\\.\\?\\!]* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding ([^\\.\\?\\!]*)[\\.\\?\\!] | +| regexplib/strings.js:49:3:49:5 | \\S+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding (\\S+)\\x20{2,}(?=\\S+) | +| regexplib/strings.js:53:25:53:33 | [a-z0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [\\-a-z0-9]* | +| regexplib/strings.js:53:65:53:73 | [a-z0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [\\-a-z0-9]* | +| regexplib/strings.js:54:20:54:22 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (NOT)?(\\s*\\(*)\\s*(\\w+)\\s*(=\|<>\|<\|>\|LIKE\|IN)\\s*(\\(([^\\)]*)\\)\|'([^']*)'\|(-?\\d*\\.?\\d+))(\\s*\\)*\\s*)(AND\|OR)? | +| regexplib/strings.js:56:52:56:53 | .+ | Strings starting with 'PRN.' and with many repetitions of '.' can start matching anywhere after the start of the preceeding .* | +| regexplib/strings.js:57:36:57:38 | .*? | Strings starting with '?se[A' and with many repetitions of '?se[Aa' can start matching anywhere after the start of the preceeding (?s)(?:\\e\\[(?:(\\d+);?)*([A-Za-z])(.*?))(?=\\e\\[\|\\z) | +| regexplib/strings.js:64:3:64:5 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (\\w+)\\s+\\1 | +| regexplib/strings.js:70:6:70:17 | [a-zA-Z,\\s]+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s* | +| regexplib/strings.js:70:18:70:20 | \\s* | Strings starting with '\\t' and with many repetitions of '\\t' can start matching anywhere after the start of the preceeding [a-zA-Z,\\s]+ | +| regexplib/strings.js:72:35:72:37 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w+\|[A-Z]?\\.?)\\s(?[A-Z]?\\w{0,3}[A-Z]\\w+\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:72:61:72:63 | \\w+ | Strings starting with 'AA' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding (?[A-Z]\\.?\\w*\\-?[A-Z]?\\w*)\\s?(?[A-Z]\\w+\|[A-Z]?\\.?)\\s(?[A-Z]?\\w{0,3}[A-Z]\\w+\\-?[A-Z]?\\w*)(?:,\\s\|)(?Jr\\.\|Sr\\.\|IV\|III\|II\|) | +| regexplib/strings.js:72:119:72:121 | \\w* | Strings with many repetitions of 'aA' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/strings.js:73:2:73:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*\\$AVE | +| regexplib/strings.js:74:2:74:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*[Pp]re[Ss\\$]cr[iI1]pt.* | +| regexplib/strings.js:75:2:75:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*[Vv][Ii1]agr.* | +| regexplib/strings.js:76:2:76:3 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding .*[Oo0][Ee][Mm].* | +| regexplib/strings.js:81:36:81:38 | .*? | Strings starting with '?se[A' and with many repetitions of '?se[Aa' can start matching anywhere after the start of the preceeding (?s)(?:\\e\\[(?:(\\d+);?)*([A-Za-z])(.*?))(?=\\e\\[\|\\z) | +| regexplib/strings.js:82:20:82:22 | \\w+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (NOT)?(\\s*\\(*)\\s*(\\w+)\\s*(=\|<>\|<\|>\|LIKE\|IN)\\s*(\\(([^\\)]*)\\)\|'([^']*)'\|(-?\\d*\\.?\\d+))(\\s*\\)*\\s*)(AND\|OR)? | +| regexplib/strings.js:88:3:88:12 | [^\\.\\?\\!]* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding ([^\\.\\?\\!]*)[\\.\\?\\!] | +| regexplib/strings.js:89:3:89:5 | \\S+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding (\\S+)\\x20{2,}(?=\\S+) | +| regexplib/uri.js:3:149:3:151 | .*? | Strings starting with 'ftp:// ' and with many repetitions of '/ /' can start matching anywhere after the start of the preceeding (?:(?http(?:s?)\|ftp)(?:\\:\\/\\/)) (?:(?\\w+\\:\\w+)(?:\\@))? (?[^/\\r\\n\\:]+)? (?\\:\\d+)? (?(?:\\/.*)*\\/)? (?.*?\\.(?\\w{2,4}))? (?\\??(?:\\w+\\=[^\\#]+)(?:\\&?\\w+\\=\\w+)*)* (?\\#.*)? | +| regexplib/uri.js:3:188:3:190 | \\w+ | Strings starting with 'ftp:// ' and with many repetitions of '00' can start matching anywhere after the start of the preceeding (?:(?http(?:s?)\|ftp)(?:\\:\\/\\/)) (?:(?\\w+\\:\\w+)(?:\\@))? (?[^/\\r\\n\\:]+)? (?\\:\\d+)? (?(?:\\/.*)*\\/)? (?.*?\\.(?\\w{2,4}))? (?\\??(?:\\w+\\=[^\\#]+)(?:\\&?\\w+\\=\\w+)*)* (?\\#.*)? | +| regexplib/uri.js:3:193:3:198 | [^\\#]+ | Strings starting with 'ftp:// a=' and with many repetitions of '00=' can start matching anywhere after the start of the preceeding (?:(?http(?:s?)\|ftp)(?:\\:\\/\\/)) (?:(?\\w+\\:\\w+)(?:\\@))? (?[^/\\r\\n\\:]+)? (?\\:\\d+)? (?(?:\\/.*)*\\/)? (?.*?\\.(?\\w{2,4}))? (?\\??(?:\\w+\\=[^\\#]+)(?:\\&?\\w+\\=\\w+)*)* (?\\#.*)? | +| regexplib/uri.js:3:206:3:208 | \\w+ | Strings starting with 'ftp:// a="' and with many repetitions of '00' can start matching anywhere after the start of the preceeding (?:(?http(?:s?)\|ftp)(?:\\:\\/\\/)) (?:(?\\w+\\:\\w+)(?:\\@))? (?[^/\\r\\n\\:]+)? (?\\:\\d+)? (?(?:\\/.*)*\\/)? (?.*?\\.(?\\w{2,4}))? (?\\??(?:\\w+\\=[^\\#]+)(?:\\&?\\w+\\=\\w+)*)* (?\\#.*)? | +| regexplib/uri.js:3:211:3:213 | \\w+ | Strings starting with 'ftp:// a="a=' and with many repetitions of '00=' can start matching anywhere after the start of the preceeding (?:(?http(?:s?)\|ftp)(?:\\:\\/\\/)) (?:(?\\w+\\:\\w+)(?:\\@))? (?[^/\\r\\n\\:]+)? (?\\:\\d+)? (?(?:\\/.*)*\\/)? (?.*?\\.(?\\w{2,4}))? (?\\??(?:\\w+\\=[^\\#]+)(?:\\&?\\w+\\=\\w+)*)* (?\\#.*)? | +| regexplib/uri.js:5:42:5:43 | .* | Strings starting with 'A:\\\\a' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [\\w ]* | +| regexplib/uri.js:14:175:14:213 | [\\d\\w\\.\\/\\%\\+\\-\\=\\&\\?\\:\\\\\\"\\'\\,\\\|\\~\\;]* | Strings with many repetitions of '.ac+' can start matching anywhere after the start of the preceeding [\\d\\w\\.\\/\\+\\-\\?\\:]* | +| regexplib/uri.js:17:42:17:43 | .* | Strings starting with 'A:\\\\a' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [\\w ]* | +| regexplib/uri.js:18:4:18:46 | ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+? | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\A([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+?([ A-Za-z0-9'~` !@#$%&^_+=\\(\\){},\\-\\[\\];]\|([.]))*?(?(3)(([ A-Za-z0-9'~`!@#$ %&^_+=\\(\\){},\\-\\[\\]\\;]*?)([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[ \\];])+\\z)\|(\\z)) | +| regexplib/uri.js:18:47:18:96 | ([ A-Za-z0-9'~` !@#$%&^_+=\\(\\){},\\-\\[\\];]\|([.]))*? | Strings starting with 'A!' and with many repetitions of '!' can start matching anywhere after the start of the preceeding ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+? | +| regexplib/uri.js:18:148:18:189 | ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[ \\];])+ | Strings starting with 'A!?3' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [ A-Za-z0-9'~`!@#$ %&^_+=\\(\\){},\\-\\[\\]\\;]*? | +| regexplib/uri.js:20:11:20:16 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:17:20:22 | [0-9]+ | Strings starting with '0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:33:20:38 | [0-9]+ | Strings starting with '00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:39:20:44 | [0-9]+ | Strings starting with '00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:55:20:60 | [0-9]+ | Strings starting with '00.00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:61:20:66 | [0-9]+ | Strings starting with '00.00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:77:20:82 | [0-9]+ | Strings starting with '00.00.00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:20:83:20:88 | [0-9]+ | Strings starting with '00.00.00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:23:2:23:74 | (((file\|gopher\|news\|nntp\|telnet\|http\|ftp\|https\|ftps\|sftp):\\/\\/)\|(www\\.))+ | Strings with many repetitions of 'www.' can start matching anywhere after the start of the preceeding (((file\|gopher\|news\|nntp\|telnet\|http\|ftp\|https\|ftps\|sftp):\\/\\/)\|(www\\.))+(([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9\\&%_\\./-~-]*)? | +| regexplib/uri.js:23:77:23:92 | [a-zA-Z0-9\\._-]+ | Strings starting with 'www.' and with many repetitions of 'www.-' can start matching anywhere after the start of the preceeding (((file\|gopher\|news\|nntp\|telnet\|http\|ftp\|https\|ftps\|sftp):\\/\\/)\|(www\\.))+ | +| regexplib/uri.js:24:11:24:16 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:17:24:22 | [0-9]+ | Strings starting with '0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:33:24:38 | [0-9]+ | Strings starting with '00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:39:24:44 | [0-9]+ | Strings starting with '00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:55:24:60 | [0-9]+ | Strings starting with '00.00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:61:24:66 | [0-9]+ | Strings starting with '00.00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:77:24:82 | [0-9]+ | Strings starting with '00.00.00.' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:24:83:24:88 | [0-9]+ | Strings starting with '00.00.00.0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [0-2]* | +| regexplib/uri.js:29:2:29:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'wwwa' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:29:48:29:62 | [a-zA-Z0-9\\.-]+ | Strings starting with 'wwwa' and with many repetitions of 'www--' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | +| regexplib/uri.js:31:65:31:69 | [^<]+ | Strings starting with 'href=! >' and with many repetitions of 'href=! >;' can start matching anywhere after the start of the preceeding href\\s*=\\s*(?:(?:\\"(?[^\\"]*)\\")\|(?[^\\s*] ))>(?[^<]+)<\\/\\w> | +| regexplib/uri.js:36:40:36:42 | \\d* | Strings starting with '$1' and with many repetitions of '1' can start matching anywhere after the start of the preceeding [1-9]+ | +| regexplib/uri.js:38:20:38:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z0-9-]* | +| regexplib/uri.js:38:35:38:40 | [a-z]+ | Strings starting with 'a.' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding ([a-z]+([a-z0-9-]*[a-z0-9]+)?)+ | +| regexplib/uri.js:38:52:38:60 | [a-z0-9]+ | Strings starting with 'a.a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding ([a-z]+([a-z0-9-]*[a-z0-9]+)?)+ | +| regexplib/uri.js:39:7:39:9 | .*? | Strings starting with '<a' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding <a\\s*.*?href\\s*=\\s*['"](?!http:\\/\\/).*?>(.*?)<\\/a> | +| regexplib/uri.js:39:43:39:45 | .*? | Strings with many repetitions of '>a' can start matching anywhere after the start of the preceeding .*? | +| regexplib/uri.js:41:16:41:31 | [a-zA-Z0-9\\-\\.]+ | Strings starting with '0' and with many repetitions of '00' can start matching anywhere after the start of the preceeding [a-zA-Z0-9]+ | +| regexplib/uri.js:47:31:47:36 | [\\w-]+ | Strings with many repetitions of '-' can start matching anywhere after the start of the preceeding [\\w-\\s]* | +| regexplib/uri.js:51:51:51:53 | \\S+ | Strings with many repetitions of '!@' can start matching anywhere after the start of the preceeding \\S+ | +| regexplib/uri.js:54:40:54:42 | \\d* | Strings starting with '$1' and with many repetitions of '1' can start matching anywhere after the start of the preceeding [1-9]+ | +| regexplib/uri.js:55:20:55:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z0-9-]* | +| regexplib/uri.js:55:35:55:40 | [a-z]+ | Strings starting with 'a.' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding ([a-z]+([a-z0-9-]*[a-z0-9]+)?)+ | +| regexplib/uri.js:55:52:55:60 | [a-z0-9]+ | Strings starting with 'a.a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding ([a-z]+([a-z0-9-]*[a-z0-9]+)?)+ | +| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'wwwa' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:58:48:58:62 | [a-zA-Z0-9\\.-]+ | Strings starting with 'wwwa' and with many repetitions of 'www--' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | +| regexplib/uri.js:64:31:64:36 | [\\w-]+ | Strings with many repetitions of '-' can start matching anywhere after the start of the preceeding [\\w-\\s]* | +| regexplib/uri.js:70:16:70:31 | [a-zA-Z0-9\\-\\.]+ | Strings starting with '0' and with many repetitions of '00' can start matching anywhere after the start of the preceeding [a-zA-Z0-9]+ | +| regexplib/uri.js:71:75:71:89 | [^\\/\\\\:*?"<>\|]+ | Strings starting with 'A:\\\\!.' and with many repetitions of '!.' can start matching anywhere after the start of the preceeding [^\\/\\\\:*?"<>\|]+ | +| tst.js:14:15:14:16 | .* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (.*,)+ | +| tst.js:23:21:23:28 | [\\s\\S]*? | Strings starting with '(*' and with many repetitions of '(*a' can start matching anywhere after the start of the preceeding (?:[\\s\\S]*?\\(\\*[\\s\\S]*?\\*\\))* | +| tst.js:23:33:23:40 | [\\s\\S]*? | Strings starting with '(*(*' and with many repetitions of '(*' can start matching anywhere after the start of the preceeding (?:[\\s\\S]*?\\(\\*[\\s\\S]*?\\*\\))* | +| tst.js:23:47:23:54 | [\\s\\S]*? | Strings starting with '(*' and with many repetitions of '(*a' can start matching anywhere after the start of the preceeding (?:[\\s\\S]*?\\(\\*[\\s\\S]*?\\*\\))* | +| tst.js:28:24:28:25 | .* | Strings starting with '!\|' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .* | +| tst.js:28:59:28:60 | .* | Strings starting with '!\|\\n-\|\\n\|' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .* | +| tst.js:31:23:31:24 | .* | Strings starting with '!\|' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .* | +| tst.js:31:54:31:55 | .* | Strings starting with '!\|\\n-\|\\n' and with many repetitions of '\|\\n\|' can start matching anywhere after the start of the preceeding .* | +| tst.js:31:58:31:59 | .* | Strings starting with '!\|\\n-\|\\n\|' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .* | +| tst.js:41:14:41:30 | ([\\s\\[\\{\\(]\|#.*)* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding .* | +| tst.js:47:21:47:43 | (?:[^"']\|".*?"\|'.*?')*? | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ((?:[^"']\|".*?"\|'.*?')*?)([(,)]\|$) | +| tst.js:47:31:47:33 | .*? | Strings starting with '"' and with many repetitions of '"' can start matching anywhere after the start of the preceeding ((?:[^"']\|".*?"\|'.*?')*?)([(,)]\|$) | +| tst.js:47:37:47:39 | .*? | Strings starting with ''' and with many repetitions of ''' can start matching anywhere after the start of the preceeding ((?:[^"']\|".*?"\|'.*?')*?)([(,)]\|$) | +| tst.js:52:34:52:43 | (\\[.*?\\])* | Strings starting with '$' and with many repetitions of '[]' can start matching anywhere after the start of the preceeding .*? | +| tst.js:52:37:52:39 | .*? | Strings starting with '$[' and with many repetitions of '[]' can start matching anywhere after the start of the preceeding (\\[.*?\\])* | +| tst.js:52:67:52:76 | (\\[.*?\\])* | Strings starting with '$.$' and with many repetitions of '[]' can start matching anywhere after the start of the preceeding (\\[.*?\\])* | +| tst.js:52:70:52:72 | .*? | Strings starting with '$.$[' and with many repetitions of '[]' can start matching anywhere after the start of the preceeding (\\[.*?\\])* | +| tst.js:58:15:58:20 | [a-z]+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([a-z]+)+ | +| tst.js:60:43:60:54 | [a-zA-Z0-9]+ | Strings starting with '0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding (([\\\\-.]\|[_]+)?([a-zA-Z0-9]+))* | +| tst.js:61:16:61:23 | ([a-z])+ | Strings with many repetitions of 'aa' can start matching anywhere after the start of the preceeding (([a-z])+.)+ | +| tst.js:66:16:66:31 | [\\w#:.~>+()\\s-]+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (([\\w#:.~>+()\\s-]+\|\\*\|\\[.*?\\])+)\\s*(,\|$) | +| tst.js:66:38:66:40 | .*? | Strings starting with '[' and with many repetitions of '[' can start matching anywhere after the start of the preceeding (([\\w#:.~>+()\\s-]+\|\\*\|\\[.*?\\])+)\\s*(,\|$) | +| tst.js:66:46:66:48 | \\s* | Strings starting with '*' and with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (([\\w#:.~>+()\\s-]+\|\\*\|\\[.*?\\])+)\\s*(,\|$) | +| tst.js:71:19:71:26 | (\\\\?.)*? | Strings starting with '"' and with many repetitions of '"' can start matching anywhere after the start of the preceeding ("\|')(\\\\?.)*?\\1 | +| tst.js:74:14:74:21 | (b\|a?b)* | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (b\|a?b)*c | +| tst.js:77:14:77:21 | (a\|aa?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa?)*b | +| tst.js:80:14:80:20 | (.\|\\n)* | Strings with many repetitions of '\\n' can start matching anywhere after the start of the preceeding (.\|\\n)*! | +| tst.js:83:14:83:20 | (.\|\\n)* | Strings with many repetitions of '\\n' can start matching anywhere after the start of the preceeding (.\|\\n)*! | +| tst.js:89:25:89:32 | (a\|aa?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a\|aa?)*b | +| tst.js:95:15:95:25 | ([^]\|[^a])* | Strings with many repetitions of '`' can start matching anywhere after the start of the preceeding (([^]\|[^a])*)" | +| tst.js:101:15:101:23 | (.\|[^a])* | Strings with many repetitions of '`' can start matching anywhere after the start of the preceeding ((.\|[^a])*)" | +| tst.js:104:16:104:24 | (a\|[^a])* | Strings with many repetitions of '`' can start matching anywhere after the start of the preceeding ((a\|[^a])*)" | +| tst.js:107:15:107:23 | (b\|[^a])* | Strings with many repetitions of '`' can start matching anywhere after the start of the preceeding ((b\|[^a])*)" | +| tst.js:110:15:110:23 | (G\|[^a])* | Strings with many repetitions of 'G' can start matching anywhere after the start of the preceeding ((G\|[^a])*)" | +| tst.js:113:15:113:27 | ([0-9]\|[^a])* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding (([0-9]\|[^a])*)" | +| tst.js:122:16:122:62 | (?:\\\\[\\x00-\\x7f]\|[^\\x00-\\x08\\x0a-\\x1f\\x7f"\\\\])* | Strings starting with '"' and with many repetitions of '\\\\"!' can start matching anywhere after the start of the preceeding "((?:\\\\[\\x00-\\x7f]\|[^\\x00-\\x08\\x0a-\\x1f\\x7f"\\\\])*)" | +| tst.js:125:15:125:28 | ([a-z]\|[d-h])* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (([a-z]\|[d-h])*)" | +| tst.js:128:15:128:30 | ([^a-z]\|[^0-9])* | Strings with many repetitions of '/' can start matching anywhere after the start of the preceeding (([^a-z]\|[^0-9])*)" | +| tst.js:131:15:131:25 | (\\d\|[0-9])* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding ((\\d\|[0-9])*)" | +| tst.js:134:15:134:22 | (\\s\|\\s)* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding ((\\s\|\\s)*)" | +| tst.js:137:15:137:21 | (\\w\|G)* | Strings with many repetitions of 'G' can start matching anywhere after the start of the preceeding ((\\w\|G)*)" | +| tst.js:140:16:140:23 | (\\s\|\\d)* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding ((\\s\|\\d)*)" | +| tst.js:143:15:143:22 | (\\d\|\\w)* | Strings with many repetitions of '9' can start matching anywhere after the start of the preceeding ((\\d\|\\w)*)" | +| tst.js:146:15:146:21 | (\\d\|5)* | Strings with many repetitions of '5' can start matching anywhere after the start of the preceeding ((\\d\|5)*)" | +| tst.js:149:15:149:24 | (\\s\|[\\f])* | Strings with many repetitions of '\u000c' can start matching anywhere after the start of the preceeding ((\\s\|[\\f])*)" | +| tst.js:152:15:152:28 | (\\s\|[\\v]\|\\\\v)* | Strings with many repetitions of '\u000b' can start matching anywhere after the start of the preceeding ((\\s\|[\\v]\|\\\\v)*)" | +| tst.js:155:15:155:24 | (\\f\|[\\f])* | Strings with many repetitions of '\u000c' can start matching anywhere after the start of the preceeding ((\\f\|[\\f])*)" | +| tst.js:158:15:158:22 | (\\W\|\\D)* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding ((\\W\|\\D)*)" | +| tst.js:161:15:161:22 | (\\S\|\\w)* | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ((\\S\|\\w)*)" | +| tst.js:164:15:164:24 | (\\S\|[\\w])* | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ((\\S\|[\\w])*)" | +| tst.js:167:15:167:27 | (1s\|[\\da-z])* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding ((1s\|[\\da-z])*)" | +| tst.js:170:15:170:23 | (0\|[\\d])* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding ((0\|[\\d])*)" | +| tst.js:173:16:173:20 | [\\d]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding (([\\d]+)*)" | +| tst.js:185:16:185:21 | [^>a]+ | Strings with many repetitions of '=' can start matching anywhere after the start of the preceeding ([^>a]+)* | +| tst.js:188:17:188:19 | \\s* | Strings starting with '\\n' and with many repetitions of '\\n' can start matching anywhere after the start of the preceeding (\\n\\s*)+$ | +| tst.js:191:18:191:20 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (?:\\s+\|#.*\|\\(\\?#[^)]*\\))* | +| tst.js:191:31:191:35 | [^)]* | Strings starting with '(?#' and with many repetitions of '(?#' can start matching anywhere after the start of the preceeding (?:\\s+\|#.*\|\\(\\?#[^)]*\\))* | +| tst.js:194:53:194:61 | [a-zA-Z]+ | Strings starting with '{[A(A)' and with many repetitions of 'AA' can start matching anywhere after the start of the preceeding [ a-zA-Z{}]+ | +| tst.js:194:68:194:79 | [ a-zA-Z{}]+ | Strings starting with '{[A(A)A:' and with many repetitions of ' A: ' can start matching anywhere after the start of the preceeding [a-zA-Z]+ | +| tst.js:194:87:194:89 | \\s* | Strings starting with '{[A(A)' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [ a-zA-Z{}]+ | +| tst.js:197:15:197:16 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a+\|b+\|c+)* | +| tst.js:197:18:197:19 | b+ | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (a+\|b+\|c+)* | +| tst.js:200:17:200:18 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (((a+a?)*)+b+) | +| tst.js:203:15:203:16 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a+)+ | +| tst.js:209:15:209:16 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a+)+ | +| tst.js:215:15:215:17 | \\n+ | Strings with many repetitions of '\\n' can start matching anywhere after the start of the preceeding (\\n+)+ | +| tst.js:218:15:218:19 | [^X]+ | Strings with many repetitions of 'W' can start matching anywhere after the start of the preceeding ([^X]+)* | +| tst.js:221:15:221:22 | ([^X]b)+ | Strings with many repetitions of 'Wb' can start matching anywhere after the start of the preceeding (([^X]b)+)* | +| tst.js:227:15:227:22 | ([^X]b)+ | Strings with many repetitions of 'Wb' can start matching anywhere after the start of the preceeding (([^X]b)+)* | +| tst.js:239:15:239:19 | (ab)+ | Strings with many repetitions of 'ab' can start matching anywhere after the start of the preceeding ((ab)+)* | +| tst.js:245:15:245:21 | [\\n\\s]+ | Strings with many repetitions of '\\n' can start matching anywhere after the start of the preceeding ([\\n\\s]+)* | +| tst.js:248:18:248:19 | A* | Strings with many repetitions of 'A' can start matching anywhere after the start of the preceeding (A*A*X)* | +| tst.js:254:15:254:17 | \\w* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:254:27:254:29 | \\w* | Strings starting with 'foobarbaz' and with many repetitions of 'foobarbaz' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:254:39:254:41 | \\w* | Strings starting with 'foobarbazfoobarbaz' and with many repetitions of 'foobarbaz' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:254:51:254:53 | \\w* | Strings starting with 'foobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbaz' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:254:63:254:65 | \\s* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:254:75:254:77 | \\d* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding (\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\w*foobarbaz\\s*foobarbaz\\d*foobarbaz\\w*)+- | +| tst.js:257:14:257:116 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | Strings with many repetitions of ' thisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)*- | +| tst.js:260:14:260:77 | (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | Strings with many repetitions of 'thisaquery' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)*- | +| tst.js:260:68:260:70 | \\w+ | Strings starting with 'this' and with many repetitions of 'this' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | +| tst.js:263:15:263:117 | (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)* | Strings with many repetitions of 'thisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)*- | +| tst.js:272:21:272:22 | b+ | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (b+)+ | +| tst.js:275:25:275:27 | \\s+ | Strings starting with '<a' and with many repetitions of ' 0=" 0=" ' can start matching anywhere after the start of the preceeding [^"]* | +| tst.js:275:28:275:30 | \\w+ | Strings starting with '<a ' and with many repetitions of '0=" 0=" ' can start matching anywhere after the start of the preceeding [^"]* | +| tst.js:275:34:275:36 | \\s* | Strings starting with '<a a' and with many repetitions of '=" 0=" 0 ' can start matching anywhere after the start of the preceeding [^"]* | +| tst.js:275:48:275:52 | [^"]* | Strings starting with '<a a="' and with many repetitions of '" a="' can start matching anywhere after the start of the preceeding (?:\\s+\\w+(?:\\s*=\\s*(?:(?:"[^"]*")\|(?:'[^']*')\|[^>\\s]+))?)* | +| tst.js:275:60:275:64 | [^']* | Strings starting with '<a a='' and with many repetitions of '' a='' can start matching anywhere after the start of the preceeding (?:\\s+\\w+(?:\\s*=\\s*(?:(?:"[^"]*")\|(?:'[^']*')\|[^>\\s]+))?)* | +| tst.js:275:68:275:74 | [^>\\s]+ | Strings starting with '<a a=' and with many repetitions of '" a="' can start matching anywhere after the start of the preceeding [^"]* | +| tst.js:281:16:281:17 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a+)* | +| tst.js:284:16:284:17 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a+)* | +| tst.js:290:16:290:17 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ((a+)*$\|[^]+) | +| tst.js:293:22:293:23 | a+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([^]+\|(a+)*$) | +| tst.js:296:15:296:24 | ((;\|^)a+)+ | Strings starting with 'a' and with many repetitions of ';a' can start matching anywhere after the start of the preceeding ((;\|^)a+)+$ | +| tst.js:296:21:296:22 | a+ | Strings with many repetitions of 'a;' can start matching anywhere after the start of the preceeding ((;\|^)a+)+$ | +| tst.js:299:90:299:91 | e+ | Strings starting with '00000000000000' and with many repetitions of 'e' can start matching anywhere after the start of the preceeding (e+)+ | +| tst.js:302:18:302:19 | c+ | Strings starting with 'ab' and with many repetitions of 'c' can start matching anywhere after the start of the preceeding (c+)+ | +| tst.js:305:18:305:20 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (\\s+)* | +| tst.js:308:16:308:24 | ([^/]\|X)+ | Strings with many repetitions of '.' can start matching anywhere after the start of the preceeding (([^/]\|X)+)(\\/[^]*)*$ | +| tst.js:311:17:311:28 | (x([^Y]+)?)* | Strings with many repetitions of 'xX' can start matching anywhere after the start of the preceeding [^Y]+ | +| tst.js:311:20:311:24 | [^Y]+ | Strings starting with 'x' and with many repetitions of 'xX' can start matching anywhere after the start of the preceeding (x([^Y]+)?)* | +| tst.js:314:15:314:16 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a*)+b | +| tst.js:317:18:317:23 | [\\w-]* | Strings starting with 'foo' and with many repetitions of 'foo-' can start matching anywhere after the start of the preceeding foo([\\w-]*)+bar | +| tst.js:320:15:320:19 | (ab)* | Strings with many repetitions of 'ab' can start matching anywhere after the start of the preceeding ((ab)*)+c | +| tst.js:323:14:323:20 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b | +| tst.js:326:15:326:19 | (a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?)*b | +| tst.js:329:14:329:20 | (c?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (c?a?)*b | +| tst.js:332:14:332:22 | (?:a\|a?)+ | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (?:a\|a?)+b | +| tst.js:335:14:335:20 | (a?b?)* | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (a?b?)*$ | diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialReDoS.expected index f1ca5be6fcb..9d30489ee27 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Performance/ReDoS/PolynomialReDoS.expected @@ -14,6 +14,10 @@ nodes | polynomial-redos.js:12:2:12:8 | tainted | | polynomial-redos.js:15:2:15:8 | tainted | | polynomial-redos.js:15:2:15:8 | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | +| polynomial-redos.js:17:23:17:29 | tainted | | polynomial-redos.js:18:2:18:8 | tainted | | polynomial-redos.js:18:2:18:8 | tainted | | polynomial-redos.js:19:2:19:8 | tainted | @@ -22,8 +26,6 @@ nodes | polynomial-redos.js:20:2:20:8 | tainted | | polynomial-redos.js:25:2:25:8 | tainted | | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:27:77:27:83 | tainted | -| polynomial-redos.js:27:77:27:83 | tainted | | polynomial-redos.js:30:2:30:8 | tainted | | polynomial-redos.js:30:2:30:8 | tainted | | polynomial-redos.js:33:2:33:8 | tainted | @@ -34,6 +36,10 @@ nodes | polynomial-redos.js:37:2:37:8 | tainted | | polynomial-redos.js:38:2:38:8 | tainted | | polynomial-redos.js:38:2:38:8 | tainted | +| polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:43:2:43:8 | tainted | +| polynomial-redos.js:43:2:43:8 | tainted | | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:50:14:50:20 | tainted | @@ -54,6 +60,8 @@ nodes | polynomial-redos.js:57:25:57:31 | tainted | | polynomial-redos.js:58:21:58:27 | tainted | | polynomial-redos.js:58:21:58:27 | tainted | +| polynomial-redos.js:59:23:59:29 | tainted | +| polynomial-redos.js:59:23:59:29 | tainted | | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:63:21:63:27 | tainted | @@ -72,26 +80,58 @@ nodes | polynomial-redos.js:69:18:69:25 | req.body | | polynomial-redos.js:69:18:69:25 | req.body | | polynomial-redos.js:69:18:69:25 | req.body | +| polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | +| polynomial-redos.js:73:2:73:8 | tainted | | polynomial-redos.js:75:2:75:8 | tainted | | polynomial-redos.js:75:2:75:8 | tainted | | polynomial-redos.js:77:2:77:8 | tainted | | polynomial-redos.js:77:2:77:8 | tainted | | polynomial-redos.js:80:2:80:8 | tainted | | polynomial-redos.js:80:2:80:8 | tainted | +| polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | +| polynomial-redos.js:88:2:88:8 | tainted | | polynomial-redos.js:89:2:89:8 | tainted | | polynomial-redos.js:89:2:89:8 | tainted | +| polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | +| polynomial-redos.js:100:2:100:8 | tainted | | polynomial-redos.js:101:2:101:8 | tainted | | polynomial-redos.js:101:2:101:8 | tainted | | polynomial-redos.js:102:2:102:8 | tainted | | polynomial-redos.js:102:2:102:8 | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | +| polynomial-redos.js:103:2:103:8 | tainted | | polynomial-redos.js:104:2:104:8 | tainted | | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:105:2:105:8 | tainted | -| polynomial-redos.js:105:2:105:8 | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | +| polynomial-redos.js:109:2:109:8 | tainted | | polynomial-redos.js:111:2:111:8 | tainted | | polynomial-redos.js:111:2:111:8 | tainted | | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:112:2:112:8 | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:116:2:116:8 | tainted | edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted | @@ -105,6 +145,10 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:12:2:12:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:15:2:15:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:16:2:16:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:17:23:17:29 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:18:2:18:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:19:2:19:8 | tainted | @@ -113,8 +157,6 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:20:2:20:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:25:2:25:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:27:77:27:83 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:27:77:27:83 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:30:2:30:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:33:2:33:8 | tainted | @@ -125,6 +167,10 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:37:2:37:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:38:2:38:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:40:2:40:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:43:2:43:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:48:2:48:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:50:14:50:20 | tainted | @@ -145,6 +191,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:57:25:57:31 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:58:21:58:27 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:59:23:59:29 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:62:17:62:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:63:21:63:27 | tainted | @@ -157,26 +205,58 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:75:2:75:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:77:2:77:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:80:2:80:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:81:2:81:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:86:2:86:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:88:2:88:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:89:2:89:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:90:2:90:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:94:2:94:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:95:2:95:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:96:2:96:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:98:2:98:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:100:2:100:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:101:2:101:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:102:2:102:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:103:2:103:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:104:2:104:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:105:2:105:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:105:2:105:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:107:2:107:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:108:2:108:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:109:2:109:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:111:2:111:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | | polynomial-redos.js:68:18:68:24 | req.url | polynomial-redos.js:68:18:68:24 | req.url | @@ -188,19 +268,26 @@ edges | polynomial-redos.js:11:2:11:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:11:2:11:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:11:19:11:20 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:12:2:12:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:12:2:12:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:12:19:12:20 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:15:2:15:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:15:28:15:35 | [\\s\\S]*? | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:18:2:18:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:18:17:18:22 | [0-9]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:15:2:15:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:15:2:15:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:15:41:15:43 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:16:2:16:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:16:2:16:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:16:25:16:32 | [\\s\\S]*? | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:17:23:17:29 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:17:5:17:6 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:17:23:17:29 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:17:23:17:29 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:17:11:17:12 | .+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:18:2:18:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:18:2:18:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:18:83:18:100 | [\\u0600-\\u06FF\\/]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:19:2:19:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:19:2:19:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:19:17:19:22 | [0-9]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:20:2:20:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:20:2:20:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:20:56:20:58 | \\d+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:25:2:25:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:25:37:25:56 | [a-zA-Z0-9+\\/ \\t\\n]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:25:2:25:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:25:2:25:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:25:63:25:64 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:27:77:27:83 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:27:77:27:83 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:27:14:27:22 | [A-Z]{2,} | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:30:2:30:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:30:19:30:22 | [?]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:30:2:30:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:30:2:30:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:30:23:30:24 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:33:2:33:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:33:2:33:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:33:17:33:20 | (.)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:36:2:36:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:36:18:36:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:36:2:36:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:36:2:36:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:36:35:36:36 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:37:2:37:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:37:18:37:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:37:2:37:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:37:2:37:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:37:35:37:36 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:38:2:38:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:38:18:38:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:38:2:38:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:38:2:38:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:38:34:38:35 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:40:2:40:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:40:2:40:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:40:51:40:63 | [?\\x21-\\x7E]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:43:2:43:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:43:2:43:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:43:67:43:72 | [^\\n]+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:48:2:48:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:48:2:48:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:48:22:48:24 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:50:14:50:20 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:50:14:50:20 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:50:4:50:5 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:51:26:51:32 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:51:26:51:32 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:51:11:51:17 | (YH\|J)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | @@ -208,10 +295,12 @@ edges | polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:53:21:53:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:53:3:53:8 | (B\|Y)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:53:21:53:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:53:21:53:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:53:9:53:12 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:54:22:54:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:54:4:54:9 | (B\|Y)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:54:22:54:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:54:22:54:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:54:10:54:13 | (.)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:55:23:55:29 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:55:23:55:29 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:55:11:55:14 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:56:22:56:28 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:56:22:56:28 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:56:10:56:13 | (Y)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:57:25:57:31 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:57:25:57:31 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:57:11:57:16 | (Y\|K)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:58:21:58:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:58:21:58:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:58:11:58:12 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:59:23:59:29 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:59:23:59:29 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:59:11:59:14 | (.)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:62:17:62:23 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:62:17:62:23 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:62:7:62:8 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:63:21:63:27 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:63:21:63:27 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:63:11:63:12 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:64:24:64:30 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:64:24:64:30 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:64:14:64:15 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | @@ -219,15 +308,30 @@ edges | polynomial-redos.js:66:19:66:25 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:66:19:66:25 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:66:9:66:10 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:67:18:67:24 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:67:18:67:24 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:67:8:67:9 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | This expensive $@ use depends on $@. | polynomial-redos.js:69:8:69:9 | .* | regular expression | polynomial-redos.js:69:18:69:25 | req.body | a user-provided value | +| polynomial-redos.js:71:2:71:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:71:2:71:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:71:51:71:63 | [?\\x21-\\x7E]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:73:2:73:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:73:2:73:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:73:50:73:51 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:75:2:75:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:75:18:75:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:75:2:75:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:75:2:75:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:75:35:75:36 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:77:2:77:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:77:2:77:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:77:18:77:19 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:80:2:80:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:80:2:80:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:80:17:80:18 | a* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:81:2:81:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:81:2:81:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:81:18:81:19 | c* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:86:2:86:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:86:2:86:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:86:25:86:29 | (ab)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:88:2:88:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:88:2:88:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:88:18:88:19 | a* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:89:2:89:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:89:2:89:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:89:20:89:21 | a* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:90:2:90:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:90:2:90:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:90:19:90:20 | a* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:94:2:94:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:94:2:94:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:94:28:94:37 | ([2-5]\|B)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:95:2:95:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:95:2:95:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:95:21:95:30 | ([2-5]\|B)* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:96:2:96:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:96:2:96:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:96:28:96:30 | \\d* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:98:2:98:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:98:2:98:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:98:25:98:29 | (ab)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:100:2:100:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:100:2:100:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:100:18:100:19 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:101:2:101:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:101:2:101:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:101:17:101:18 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:102:2:102:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:102:2:102:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:102:20:102:21 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:103:2:103:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:103:2:103:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:103:19:103:20 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:104:2:104:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:104:2:104:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:104:17:104:18 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:105:2:105:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:105:17:105:18 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:105:2:105:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:105:19:105:20 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:105:2:105:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:105:2:105:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:105:21:105:22 | a+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:107:2:107:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:107:2:107:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:107:28:107:37 | ([2-5]\|B)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:108:2:108:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:108:2:108:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:108:21:108:30 | ([2-5]\|B)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:109:2:109:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:109:2:109:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:109:28:109:30 | \\d+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:111:2:111:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:111:2:111:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:111:17:111:19 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:112:2:112:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:112:2:112:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:112:17:112:19 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:114:2:114:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:114:2:114:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:114:22:114:24 | \\w* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:116:2:116:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:116:2:116:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:116:21:116:28 | [\\d\\D]*? | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/polynomial-redos.js b/javascript/ql/test/query-tests/Performance/ReDoS/polynomial-redos.js index 11c28b43a21..fd113d56bb5 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/polynomial-redos.js +++ b/javascript/ql/test/query-tests/Performance/ReDoS/polynomial-redos.js @@ -12,9 +12,9 @@ app.use(function(req, res) { tainted.replace(/.*\./, ''); // NOT OK tainted.replace(/^.*[/\\]/, ''); // OK tainted.replace(/^.*\./, ''); // OK - tainted.replace(/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/); // NOT OK - but not detected - tainted.replace(/^(`+)([\s\S]*?[^`])\1(?!`)/); // NOT OK - but not detected - /^(.*,)+(.+)?$/.test(tainted); // NOT OK - but only flagged by js/redos + tainted.replace(/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/); // NOT OK + tainted.replace(/^(`+)([\s\S]*?[^`])\1(?!`)/); // NOT OK + /^(.*,)+(.+)?$/.test(tainted); // NOT OK tainted.match(/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i); // NOT OK tainted.match(/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i); // NOT OK (even though it is a proposed fix for the above) tainted.match(/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/); // NOT OK @@ -24,7 +24,7 @@ app.use(function(req, res) { tainted.match(/^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/); // NOT OK tainted.match(/^([a-z0-9-]+)[ \t\n]+([a-zA-Z0-9+\/][a-zA-Z0-9+\/ \t\n=]*)([^a-zA-Z0-9+\/ \t\n=].*)?$/); // OK - /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/.test(tainted); // NOT OK + /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/.test(tainted); // NOT OK - but not detected due to not supporting ranges /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/.test(tainted); // OK tainted.replace(/[?]+.*$/g, ""); // OK - can not fail - but still flagged @@ -37,13 +37,13 @@ app.use(function(req, res) { tainted.match(/<.*style="([^"]+)".*>/); // NOT OK tainted.match(/<.*href="([^"]+)".*>/); // NOT OK - tainted.match(/^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/); // NOT OK - but not flagged + tainted.match(/^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/); // NOT OK tainted.match(/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/); // NOT OK (it is a fix for the above, but it introduces exponential complexity elsewhere) - tainted.match(/^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/); // NOT OK - but not flagged due to lack of support for inverted character classes + tainted.match(/^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/); // NOT OK tainted.match(/^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([ \t]+([^ \t][^\n]*[\n]*)?)?$/); // OK - tainted.match(/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)+$/); // NOT OK - but only flagged by js/redos + tainted.match(/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)+$/); // NOT OK (also flagged by js/redos) tainted.match(/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/); // OK tainted.replaceAll(/\s*\n\s*/g, ' '); // NOT OK @@ -56,7 +56,7 @@ app.use(function(req, res) { /f(B|Y)+(Y)*X/.test(tainted) // NOT OK (/f(B|Y)+(Y|K)*X/.test(tainted)) // NOT OK (/f(B|Y)+.*X/.test(tainted)) // NOT OK - (/f(B|Y)+(.)*X/.test(tainted)) // NOT OK - but not flagged + (/f(B|Y)+(.)*X/.test(tainted)) // NOT OK (/^(.)*X/.test(tainted)); // OK (/^Y(Y)*X/.test(tainted)); // OK (/^Y*Y*X/.test(tainted)); // NOT OK @@ -68,50 +68,50 @@ app.use(function(req, res) { (/[^Y].*$/.test(req.url)); // OK - the input cannot contain newlines. (/[^Y].*$/.test(req.body)); // NOT OK - tainted.match(/^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/); // NOT OK - but not detected + tainted.match(/^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/); // NOT OK - tainted.match(new RegExp("(MSIE) (\\d+)\\.(\\d+).*XBLWP7")); // NOT OK - but not detected + tainted.match(new RegExp("(MSIE) (\\d+)\\.(\\d+).*XBLWP7")); // NOT OK - tainted.match(/<.*class="([^"]+)".*>/); // NOT OK - but not detected + tainted.match(/<.*class="([^"]+)".*>/); // NOT OK tainted.match(/Y.*X/); // NOT OK tatined.match(/B?(YH|K)(YH|J)*X/); // NOT OK - but not detected tainted.match(/a*b/); // NOT OK - the initial repetition can start matching anywhere. - tainted.match(/cc*D/); // NOT OK - but flagged + tainted.match(/cc*D/); // NOT OK tainted.match(/^ee*F/); // OK tainted.match(/^g*g*/); // OK tainted.match(/^h*i*/); // OK - tainted.match(/^(ab)*ab(ab)*X/); // NOT OK - but not flagged + tainted.match(/^(ab)*ab(ab)*X/); // NOT OK - tainted.match(/aa*X/); // NOT OK - but not flagged + tainted.match(/aa*X/); // NOT OK tainted.match(/^a*a*X/); // NOT OK - tainted.match(/\wa*X/); // NOT OK - but not flagged + tainted.match(/\wa*X/); // NOT OK tainted.match(/a*b*c*/); // OK tainted.match(/a*a*a*a*/); // OK - tainted.match(/^([3-7]|A)*([2-5]|B)*X/); // NOT OK - but not flagged - tainted.match(/^\d*([2-5]|B)*X/); // NOT OK - but not flagged - tainted.match(/^([3-7]|A)*\d*X/); // NOT OK - but not flagged + tainted.match(/^([3-7]|A)*([2-5]|B)*X/); // NOT OK + tainted.match(/^\d*([2-5]|B)*X/); // NOT OK + tainted.match(/^([3-7]|A)*\d*X/); // NOT OK - tainted.match(/^(ab)+ab(ab)+X/); // NOT OK - but not flagged + tainted.match(/^(ab)+ab(ab)+X/); // NOT OK - tainted.match(/aa+X/); // NOT OK - but not flagged + tainted.match(/aa+X/); // NOT OK tainted.match(/a+X/); // NOT OK tainted.match(/^a+a+X/); // NOT OK - tainted.match(/\wa+X/); // NOT OK - but not flagged + tainted.match(/\wa+X/); // NOT OK tainted.match(/a+b+c+/); //NOT OK - tainted.match(/a+a+a+a+/); // OK - but is flagged + tainted.match(/a+a+a+a+/); // OK - tainted.match(/^([3-7]|A)+([2-5]|B)+X/); // NOT OK - but not flagged - tainted.match(/^\d+([2-5]|B)+X/); // NOT OK - but not flagged - tainted.match(/^([3-7]|A)+\d+X/); // NOT OK - but not flagged + tainted.match(/^([3-7]|A)+([2-5]|B)+X/); // NOT OK + tainted.match(/^\d+([2-5]|B)+X/); // NOT OK + tainted.match(/^([3-7]|A)+\d+X/); // NOT OK tainted.match(/\s*$/); // NOT OK tainted.match(/\s+$/); // NOT OK - tainted.match(/^\d*5\w*$/); // NOT OK - but not flagged + tainted.match(/^\d*5\w*$/); // NOT OK - tainted.match(/\/\*[\d\D]*?\*\//g); // NOT OK - but not flagged + tainted.match(/\/\*[\d\D]*?\*\//g); // NOT OK });