Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f5809a7

Browse files
smowtonjoefarebrother
authored andcommitted
ReDoS performance fixes
1 parent 2d96317 commit f5809a7

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

java/ql/lib/semmle/code/java/regex/RegexTreeView.qll

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ class RegExpTerm extends RegExpParent {
157157
/** Gets the offset at which this term ends. */
158158
int getEnd() { result = end }
159159

160+
/** Holds if this term occurs in regex `inRe` offsets `startOffset` to `endOffset`. */
161+
predicate occursInRegex(Regex inRe, int startOffset, int endOffset) {
162+
inRe = re and startOffset = start and endOffset = end
163+
}
164+
160165
override string toString() { result = re.getText().substring(start, end) }
161166

162167
/**
@@ -385,18 +390,15 @@ private RegExpTerm seqChild(Regex re, int start, int end, int i) {
385390
re.sequence(start, end) and
386391
(
387392
i = 0 and
388-
result.getRegex() = re and
389-
result.getStart() = start and
390393
exists(int itemEnd |
391394
re.item(start, itemEnd) and
392-
result.getEnd() = itemEnd
395+
result.occursInRegex(re, start, itemEnd)
393396
)
394397
or
395398
i > 0 and
396-
result.getRegex() = re and
397399
exists(int itemStart | itemStart = seqChildEnd(re, start, end, i - 1) |
398-
result.getStart() = itemStart and
399-
re.item(itemStart, result.getEnd())
400+
re.item(itemStart, result.getEnd()) and
401+
result.occursInRegex(re, itemStart, _)
400402
)
401403
)
402404
}
@@ -642,18 +644,15 @@ class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass {
642644

643645
override RegExpTerm getChild(int i) {
644646
i = 0 and
645-
result.getRegex() = re and
646647
exists(int itemStart, int itemEnd |
647-
result.getStart() = itemStart and
648648
re.charSetStart(start, itemStart) and
649649
re.charSetChild(start, itemStart, itemEnd) and
650-
result.getEnd() = itemEnd
650+
result.occursInRegex(re, itemStart, itemEnd)
651651
)
652652
or
653653
i > 0 and
654-
result.getRegex() = re and
655654
exists(int itemStart | itemStart = this.getChild(i - 1).getEnd() |
656-
result.getStart() = itemStart and
655+
result.occursInRegex(re, itemStart, _) and
657656
re.charSetChild(start, itemStart, result.getEnd())
658657
)
659658
}
@@ -823,6 +822,16 @@ class RegExpGroup extends RegExpTerm, TRegExpGroup {
823822
}
824823

825824
override string getPrimaryQLClass() { result = "RegExpGroup" }
825+
826+
/** Holds if this is the `n`th numbered group of literal `lit`. */
827+
predicate isNumberedGroupOfLiteral(RegExpLiteral lit, int n) {
828+
lit = this.getLiteral() and n = this.getNumber()
829+
}
830+
831+
/** Holds if this is a group with name `name` of literal `lit`. */
832+
predicate isNamedGroupOfLiteral(RegExpLiteral lit, string name) {
833+
lit = this.getLiteral() and name = this.getName()
834+
}
826835
}
827836

828837
/**
@@ -1054,11 +1063,9 @@ class RegExpBackRef extends RegExpTerm, TRegExpBackRef {
10541063

10551064
/** Gets the capture group this back reference refers to. */
10561065
RegExpGroup getGroup() {
1057-
result.getLiteral() = this.getLiteral() and
1058-
(
1059-
result.getNumber() = this.getNumber() or
1060-
result.getName() = this.getName()
1061-
)
1066+
result.isNumberedGroupOfLiteral(this.getLiteral(), this.getNumber())
1067+
or
1068+
result.isNamedGroupOfLiteral(this.getLiteral(), this.getName())
10621069
}
10631070

10641071
override RegExpTerm getChild(int i) { none() }

0 commit comments

Comments
 (0)