Skip to content

Commit 2d82dfb

Browse files
Reorder backreference predicates
1 parent 9078e13 commit 2d82dfb

File tree

1 file changed

+45
-45
lines changed

1 file changed

+45
-45
lines changed

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

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,51 @@ abstract class RegexString extends StringLiteral {
107107
end = start + 3
108108
}
109109

110+
private predicate namedBackreference(int start, int end, string name) {
111+
this.escapingChar(start) and
112+
this.getChar(start + 1) = "k" and
113+
this.getChar(start + 2) = "<" and
114+
end = min(int i | i > start + 2 and this.getChar(i) = ">") + 1 and
115+
name = this.getText().substring(start + 3, end - 2)
116+
}
117+
118+
private predicate numberedBackreference(int start, int end, int value) {
119+
this.escapingChar(start) and
120+
// starting with 0 makes it an octal escape
121+
not this.getChar(start + 1) = "0" and
122+
exists(string text, string svalue, int len |
123+
end = start + len and
124+
text = this.getText() and
125+
len in [2 .. 3]
126+
|
127+
svalue = text.substring(start + 1, start + len) and
128+
value = svalue.toInt() and
129+
// value is composed of digits
130+
forall(int i | i in [start + 1 .. start + len - 1] | this.getChar(i) = [0 .. 9].toString()) and
131+
// a longer reference is not possible
132+
not (
133+
len = 2 and
134+
exists(text.substring(start + 1, start + len + 1).toInt())
135+
) and
136+
// 3 octal digits makes it an octal escape
137+
not forall(int i | i in [start + 1 .. start + 4] | this.isOctal(i))
138+
// TODO: Inside a character set, all numeric escapes are treated as characters.
139+
)
140+
}
141+
142+
/** Holds if the text in the range start,end is a back reference */
143+
predicate backreference(int start, int end) {
144+
this.numberedBackreference(start, end, _)
145+
or
146+
this.namedBackreference(start, end, _)
147+
}
148+
149+
/** Gets the number of the back reference in start,end */
150+
int getBackrefNumber(int start, int end) { this.numberedBackreference(start, end, result) }
151+
152+
/** Gets the name, if it has one, of the back reference in start,end */
153+
string getBackrefName(int start, int end) { this.namedBackreference(start, end, result) }
154+
110155
pragma[inline]
111156
private predicate isOctal(int index) { this.getChar(index) = [0 .. 7].toString() }
112157

@@ -592,51 +637,6 @@ abstract class RegexString extends StringLiteral {
592637
this.positiveLookbehindAssertionGroup(start, end)
593638
}
594639

595-
private predicate namedBackreference(int start, int end, string name) {
596-
this.escapingChar(start) and
597-
this.getChar(start + 1) = "k" and
598-
this.getChar(start + 2) = "<" and
599-
end = min(int i | i > start + 2 and this.getChar(i) = ">") + 1 and
600-
name = this.getText().substring(start + 3, end - 2)
601-
}
602-
603-
private predicate numberedBackreference(int start, int end, int value) {
604-
this.escapingChar(start) and
605-
// starting with 0 makes it an octal escape
606-
not this.getChar(start + 1) = "0" and
607-
exists(string text, string svalue, int len |
608-
end = start + len and
609-
text = this.getText() and
610-
len in [2 .. 3]
611-
|
612-
svalue = text.substring(start + 1, start + len) and
613-
value = svalue.toInt() and
614-
// value is composed of digits
615-
forall(int i | i in [start + 1 .. start + len - 1] | this.getChar(i) = [0 .. 9].toString()) and
616-
// a longer reference is not possible
617-
not (
618-
len = 2 and
619-
exists(text.substring(start + 1, start + len + 1).toInt())
620-
) and
621-
// 3 octal digits makes it an octal escape
622-
not forall(int i | i in [start + 1 .. start + 4] | this.isOctal(i))
623-
// TODO: Inside a character set, all numeric escapes are treated as characters.
624-
)
625-
}
626-
627-
/** Holds if the text in the range start,end is a back reference */
628-
predicate backreference(int start, int end) {
629-
this.numberedBackreference(start, end, _)
630-
or
631-
this.namedBackreference(start, end, _)
632-
}
633-
634-
/** Gets the number of the back reference in start,end */
635-
int getBackrefNumber(int start, int end) { this.numberedBackreference(start, end, result) }
636-
637-
/** Gets the name, if it has one, of the back reference in start,end */
638-
string getBackrefName(int start, int end) { this.namedBackreference(start, end, result) }
639-
640640
private predicate baseItem(int start, int end) {
641641
this.character(start, end) and
642642
not exists(int x, int y | this.charSet(x, y) and x <= start and y >= end)

0 commit comments

Comments
 (0)