Skip to content

Commit a89220d

Browse files
committed
regex-syntax: fix nest limit checker
This commit fixes an embarrassing bug where the depth in the nest limit checker was never decremented during postorder traversal, which means long but shallow regexes would incorrectly trip the nest limit. We fix that in this commit and add two regression tests. Fixes #454
1 parent 649762d commit a89220d

File tree

3 files changed

+348
-1
lines changed

3 files changed

+348
-1
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
TBD
2+
===
3+
Bug gixes:
4+
5+
* [BUG #454](https://github.com/rust-lang/regex/pull/454):
6+
Fix a bug in the nest limit checker being too aggressive.
7+
8+
19
0.2.7 (2018-03-07)
210
==================
311
This release includes a ground-up rewrite of the regex-syntax crate, which has

regex-syntax/src/ast/parse.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -2106,7 +2106,7 @@ impl<'p, 's, P: Borrow<Parser>> NestLimiter<'p, 's, P> {
21062106
fn decrement_depth(&mut self) {
21072107
// Assuming the correctness of the visitor, this should never drop
21082108
// below 0.
2109-
self.depth.checked_sub(1).unwrap();
2109+
self.depth = self.depth.checked_sub(1).unwrap();
21102110
}
21112111
}
21122112

@@ -5254,4 +5254,47 @@ bar
52545254
],
52555255
})));
52565256
}
5257+
5258+
// This tests a bug fix where the nest limit checker wasn't decrementing
5259+
// its depth during post-traversal, which causes long regexes to trip
5260+
// the default limit too aggressively.
5261+
#[test]
5262+
fn regression_454_nest_too_big() {
5263+
let pattern = r#"
5264+
2(?:
5265+
[45]\d{3}|
5266+
7(?:
5267+
1[0-267]|
5268+
2[0-289]|
5269+
3[0-29]|
5270+
4[01]|
5271+
5[1-3]|
5272+
6[013]|
5273+
7[0178]|
5274+
91
5275+
)|
5276+
8(?:
5277+
0[125]|
5278+
[139][1-6]|
5279+
2[0157-9]|
5280+
41|
5281+
6[1-35]|
5282+
7[1-5]|
5283+
8[1-8]|
5284+
90
5285+
)|
5286+
9(?:
5287+
0[0-2]|
5288+
1[0-4]|
5289+
2[568]|
5290+
3[3-6]|
5291+
5[5-7]|
5292+
6[0167]|
5293+
7[15]|
5294+
8[0146-9]
5295+
)
5296+
)\d{4}
5297+
"#;
5298+
assert!(parser_nest_limit(pattern, 50).parse().is_ok());
5299+
}
52575300
}

tests/crazy.rs

+296
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,299 @@ fn dfa_handles_pathological_case() {
103103
};
104104
assert!(re.is_match(text!(&*text)));
105105
}
106+
107+
#[test]
108+
fn nest_limit_makes_it_parse() {
109+
use regex::RegexBuilder;
110+
111+
RegexBuilder::new(
112+
r#"
113+
2(?:
114+
[45]\d{3}|
115+
7(?:
116+
1[0-267]|
117+
2[0-289]|
118+
3[0-29]|
119+
4[01]|
120+
5[1-3]|
121+
6[013]|
122+
7[0178]|
123+
91
124+
)|
125+
8(?:
126+
0[125]|
127+
[139][1-6]|
128+
2[0157-9]|
129+
41|
130+
6[1-35]|
131+
7[1-5]|
132+
8[1-8]|
133+
90
134+
)|
135+
9(?:
136+
0[0-2]|
137+
1[0-4]|
138+
2[568]|
139+
3[3-6]|
140+
5[5-7]|
141+
6[0167]|
142+
7[15]|
143+
8[0146-9]
144+
)
145+
)\d{4}|
146+
3(?:
147+
12?[5-7]\d{2}|
148+
0(?:
149+
2(?:
150+
[025-79]\d|
151+
[348]\d{1,2}
152+
)|
153+
3(?:
154+
[2-4]\d|
155+
[56]\d?
156+
)
157+
)|
158+
2(?:
159+
1\d{2}|
160+
2(?:
161+
[12]\d|
162+
[35]\d{1,2}|
163+
4\d?
164+
)
165+
)|
166+
3(?:
167+
1\d{2}|
168+
2(?:
169+
[2356]\d|
170+
4\d{1,2}
171+
)
172+
)|
173+
4(?:
174+
1\d{2}|
175+
2(?:
176+
2\d{1,2}|
177+
[47]|
178+
5\d{2}
179+
)
180+
)|
181+
5(?:
182+
1\d{2}|
183+
29
184+
)|
185+
[67]1\d{2}|
186+
8(?:
187+
1\d{2}|
188+
2(?:
189+
2\d{2}|
190+
3|
191+
4\d
192+
)
193+
)
194+
)\d{3}|
195+
4(?:
196+
0(?:
197+
2(?:
198+
[09]\d|
199+
7
200+
)|
201+
33\d{2}
202+
)|
203+
1\d{3}|
204+
2(?:
205+
1\d{2}|
206+
2(?:
207+
[25]\d?|
208+
[348]\d|
209+
[67]\d{1,2}
210+
)
211+
)|
212+
3(?:
213+
1\d{2}(?:
214+
\d{2}
215+
)?|
216+
2(?:
217+
[045]\d|
218+
[236-9]\d{1,2}
219+
)|
220+
32\d{2}
221+
)|
222+
4(?:
223+
[18]\d{2}|
224+
2(?:
225+
[2-46]\d{2}|
226+
3
227+
)|
228+
5[25]\d{2}
229+
)|
230+
5(?:
231+
1\d{2}|
232+
2(?:
233+
3\d|
234+
5
235+
)
236+
)|
237+
6(?:
238+
[18]\d{2}|
239+
2(?:
240+
3(?:
241+
\d{2}
242+
)?|
243+
[46]\d{1,2}|
244+
5\d{2}|
245+
7\d
246+
)|
247+
5(?:
248+
3\d?|
249+
4\d|
250+
[57]\d{1,2}|
251+
6\d{2}|
252+
8
253+
)
254+
)|
255+
71\d{2}|
256+
8(?:
257+
[18]\d{2}|
258+
23\d{2}|
259+
54\d{2}
260+
)|
261+
9(?:
262+
[18]\d{2}|
263+
2[2-5]\d{2}|
264+
53\d{1,2}
265+
)
266+
)\d{3}|
267+
5(?:
268+
02[03489]\d{2}|
269+
1\d{2}|
270+
2(?:
271+
1\d{2}|
272+
2(?:
273+
2(?:
274+
\d{2}
275+
)?|
276+
[457]\d{2}
277+
)
278+
)|
279+
3(?:
280+
1\d{2}|
281+
2(?:
282+
[37](?:
283+
\d{2}
284+
)?|
285+
[569]\d{2}
286+
)
287+
)|
288+
4(?:
289+
1\d{2}|
290+
2[46]\d{2}
291+
)|
292+
5(?:
293+
1\d{2}|
294+
26\d{1,2}
295+
)|
296+
6(?:
297+
[18]\d{2}|
298+
2|
299+
53\d{2}
300+
)|
301+
7(?:
302+
1|
303+
24
304+
)\d{2}|
305+
8(?:
306+
1|
307+
26
308+
)\d{2}|
309+
91\d{2}
310+
)\d{3}|
311+
6(?:
312+
0(?:
313+
1\d{2}|
314+
2(?:
315+
3\d{2}|
316+
4\d{1,2}
317+
)
318+
)|
319+
2(?:
320+
2[2-5]\d{2}|
321+
5(?:
322+
[3-5]\d{2}|
323+
7
324+
)|
325+
8\d{2}
326+
)|
327+
3(?:
328+
1|
329+
2[3478]
330+
)\d{2}|
331+
4(?:
332+
1|
333+
2[34]
334+
)\d{2}|
335+
5(?:
336+
1|
337+
2[47]
338+
)\d{2}|
339+
6(?:
340+
[18]\d{2}|
341+
6(?:
342+
2(?:
343+
2\d|
344+
[34]\d{2}
345+
)|
346+
5(?:
347+
[24]\d{2}|
348+
3\d|
349+
5\d{1,2}
350+
)
351+
)
352+
)|
353+
72[2-5]\d{2}|
354+
8(?:
355+
1\d{2}|
356+
2[2-5]\d{2}
357+
)|
358+
9(?:
359+
1\d{2}|
360+
2[2-6]\d{2}
361+
)
362+
)\d{3}|
363+
7(?:
364+
(?:
365+
02|
366+
[3-589]1|
367+
6[12]|
368+
72[24]
369+
)\d{2}|
370+
21\d{3}|
371+
32
372+
)\d{3}|
373+
8(?:
374+
(?:
375+
4[12]|
376+
[5-7]2|
377+
1\d?
378+
)|
379+
(?:
380+
0|
381+
3[12]|
382+
[5-7]1|
383+
217
384+
)\d
385+
)\d{4}|
386+
9(?:
387+
[35]1|
388+
(?:
389+
[024]2|
390+
81
391+
)\d|
392+
(?:
393+
1|
394+
[24]1
395+
)\d{2}
396+
)\d{3}
397+
"#
398+
)
399+
.build()
400+
.unwrap();
401+
}

0 commit comments

Comments
 (0)