Skip to content

Commit 8e52fc9

Browse files
committed
changes based on review by Shack
1 parent 220ff3c commit 8e52fc9

File tree

4 files changed

+84
-160
lines changed

4 files changed

+84
-160
lines changed

java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,16 @@ predicate isAlphanumeric(string char) {
4242
predicate overlap(RegExpCharacterRange a, RegExpCharacterRange b) {
4343
exists(RegExpCharacterClass clz |
4444
a = clz.getAChild() and
45-
b = clz.getAChild()
45+
b = clz.getAChild() and
46+
a != b
4647
|
47-
// b contains the lower end of a
4848
exists(int alow, int ahigh, int blow, int bhigh |
4949
isRange(a, alow, ahigh) and
5050
isRange(b, blow, bhigh) and
51-
blow <= alow and
52-
bhigh >= ahigh
53-
)
54-
or
55-
// b contains the upper end of a
56-
exists(int blow, int bhigh, int alow, int ahigh |
57-
isRange(a, alow, ahigh) and
58-
isRange(b, blow, bhigh) and
59-
blow <= ahigh and
60-
bhigh >= ahigh
51+
alow <= bhigh and
52+
blow <= ahigh
6153
)
6254
)
63-
or
64-
// symmetric overlap
65-
overlap(b, a)
6655
}
6756

6857
/**
@@ -106,8 +95,8 @@ class OverlyWideRange extends RegExpCharacterRange {
10695
toCodePoint("9") >= low and
10796
toCodePoint("A") <= high
10897
or
109-
// any non-alpha numeric as part of the range
110-
not isAlphanumeric([low, high].toUnicode())
98+
// a non-alphanumeric char as part of the range boundaries
99+
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode()))
111100
) and
112101
// allowlist for known ranges
113102
not this = allowedWideRanges()
@@ -141,6 +130,7 @@ private string getInRange(string low, string high) {
141130
/** A module computing an equivalent character class for an overly wide range. */
142131
module RangePrinter {
143132
bindingset[char]
133+
bindingset[result]
144134
private string next(string char) {
145135
exists(int prev, int next |
146136
prev.toUnicode() = char and
@@ -149,15 +139,6 @@ module RangePrinter {
149139
)
150140
}
151141

152-
bindingset[char]
153-
private string prev(string char) {
154-
exists(int prev, int next |
155-
prev.toUnicode() = char and
156-
next.toUnicode() = result and
157-
next = prev - 1
158-
)
159-
}
160-
161142
/** Gets the points where the parts of the pretty printed range should be cut off. */
162143
private string cutoffs() { result = ["A", "Z", "a", "z", "0", "9"] }
163144

@@ -176,7 +157,7 @@ module RangePrinter {
176157
result = cut
177158
or
178159
cut = ["A", "a", "0"] and
179-
result = prev(cut)
160+
next(result) = cut
180161
}
181162

182163
/** Gets the cutoff char used for a given `part` of a range when pretty-printing it. */
@@ -209,25 +190,21 @@ module RangePrinter {
209190
or
210191
// middle
211192
part >= 1 and
212-
part < parts(range) and
193+
part < parts(range) - 1 and
213194
low = lowCut(cutoff(range, part - 1)) and
214195
high = highCut(cutoff(range, part))
215196
or
216197
// last.
217-
part = parts(range) and
218-
low = lowCut(cutoff(range, part - 2)) and
198+
part = parts(range) - 1 and
199+
low = lowCut(cutoff(range, part - 1)) and
219200
range.isRange(_, high)
220201
}
221202

222203
/** Gets an escaped `char` for use in a character class. */
223204
bindingset[char]
224205
private string escape(string char) {
225206
exists(string reg | reg = "(\\[|\\]|\\\\|-|/)" |
226-
char.regexpMatch(reg) and
227-
result = "\\" + char
228-
or
229-
not char.regexpMatch(reg) and
230-
result = char
207+
if char.regexpMatch(reg) then result = "\\" + char else result = char
231208
)
232209
}
233210

@@ -247,16 +224,19 @@ module RangePrinter {
247224
/** Gets the entire pretty printed equivalent range. */
248225
string printEquivalentCharClass(OverlyWideRange range) {
249226
result =
250-
"[" +
251-
strictconcat(string r, int part |
252-
r = printEquivalentCharClass(range, part)
253-
|
254-
r order by part
255-
) + "]"
227+
strictconcat(string r, int part |
228+
r = "[" and part = -1 and exists(range)
229+
or
230+
r = printEquivalentCharClass(range, part)
231+
or
232+
r = "]" and part = parts(range)
233+
|
234+
r order by part
235+
)
256236
}
257237
}
258238

259-
/** Gets a char range that is suspiciously because of `reason`. */
239+
/** Gets a char range that is overly large because of `reason`. */
260240
RegExpCharacterRange getABadRange(string reason, int priority) {
261241
priority = 0 and
262242
reason = "is equivalent to " + result.(OverlyWideRange).printEquivalent()
@@ -285,7 +265,6 @@ RegExpCharacterRange getABadRange(string reason, int priority) {
285265

286266
/** Holds if `range` matches suspiciously many characters. */
287267
predicate problem(RegExpCharacterRange range, string reason) {
288-
range = getABadRange(_, _) and
289268
reason =
290269
strictconcat(string m, int priority |
291270
range = getABadRange(m, priority)

javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ predicate overlap(RegExpCharacterRange a, RegExpCharacterRange b) {
5252
blow <= ahigh
5353
)
5454
)
55-
or
56-
// symmetric overlap
57-
overlap(b, a)
5855
}
5956

6057
/**
@@ -98,8 +95,8 @@ class OverlyWideRange extends RegExpCharacterRange {
9895
toCodePoint("9") >= low and
9996
toCodePoint("A") <= high
10097
or
101-
// any non-alpha numeric as part of the range
102-
not isAlphanumeric([low, high].toUnicode())
98+
// a non-alphanumeric char as part of the range boundaries
99+
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode()))
103100
) and
104101
// allowlist for known ranges
105102
not this = allowedWideRanges()
@@ -133,6 +130,7 @@ private string getInRange(string low, string high) {
133130
/** A module computing an equivalent character class for an overly wide range. */
134131
module RangePrinter {
135132
bindingset[char]
133+
bindingset[result]
136134
private string next(string char) {
137135
exists(int prev, int next |
138136
prev.toUnicode() = char and
@@ -141,15 +139,6 @@ module RangePrinter {
141139
)
142140
}
143141

144-
bindingset[char]
145-
private string prev(string char) {
146-
exists(int prev, int next |
147-
prev.toUnicode() = char and
148-
next.toUnicode() = result and
149-
next = prev - 1
150-
)
151-
}
152-
153142
/** Gets the points where the parts of the pretty printed range should be cut off. */
154143
private string cutoffs() { result = ["A", "Z", "a", "z", "0", "9"] }
155144

@@ -168,7 +157,7 @@ module RangePrinter {
168157
result = cut
169158
or
170159
cut = ["A", "a", "0"] and
171-
result = prev(cut)
160+
next(result) = cut
172161
}
173162

174163
/** Gets the cutoff char used for a given `part` of a range when pretty-printing it. */
@@ -201,25 +190,21 @@ module RangePrinter {
201190
or
202191
// middle
203192
part >= 1 and
204-
part < parts(range) and
193+
part < parts(range) - 1 and
205194
low = lowCut(cutoff(range, part - 1)) and
206195
high = highCut(cutoff(range, part))
207196
or
208197
// last.
209-
part = parts(range) and
210-
low = lowCut(cutoff(range, part - 2)) and
198+
part = parts(range) - 1 and
199+
low = lowCut(cutoff(range, part - 1)) and
211200
range.isRange(_, high)
212201
}
213202

214203
/** Gets an escaped `char` for use in a character class. */
215204
bindingset[char]
216205
private string escape(string char) {
217206
exists(string reg | reg = "(\\[|\\]|\\\\|-|/)" |
218-
char.regexpMatch(reg) and
219-
result = "\\" + char
220-
or
221-
not char.regexpMatch(reg) and
222-
result = char
207+
if char.regexpMatch(reg) then result = "\\" + char else result = char
223208
)
224209
}
225210

@@ -239,16 +224,19 @@ module RangePrinter {
239224
/** Gets the entire pretty printed equivalent range. */
240225
string printEquivalentCharClass(OverlyWideRange range) {
241226
result =
242-
"[" +
243-
strictconcat(string r, int part |
244-
r = printEquivalentCharClass(range, part)
245-
|
246-
r order by part
247-
) + "]"
227+
strictconcat(string r, int part |
228+
r = "[" and part = -1 and exists(range)
229+
or
230+
r = printEquivalentCharClass(range, part)
231+
or
232+
r = "]" and part = parts(range)
233+
|
234+
r order by part
235+
)
248236
}
249237
}
250238

251-
/** Gets a char range that is suspiciously because of `reason`. */
239+
/** Gets a char range that is overly large because of `reason`. */
252240
RegExpCharacterRange getABadRange(string reason, int priority) {
253241
priority = 0 and
254242
reason = "is equivalent to " + result.(OverlyWideRange).printEquivalent()
@@ -277,7 +265,6 @@ RegExpCharacterRange getABadRange(string reason, int priority) {
277265

278266
/** Holds if `range` matches suspiciously many characters. */
279267
predicate problem(RegExpCharacterRange range, string reason) {
280-
range = getABadRange(_, _) and
281268
reason =
282269
strictconcat(string m, int priority |
283270
range = getABadRange(m, priority)

0 commit comments

Comments
 (0)