Skip to content

Commit 841022a

Browse files
committed
syntax: fix overflow for big counted repetitions
This fixes a bug where the calculation for the min/max length of a regex could overflow if the counted repetitions in the pattern are big enough. The panic only happens when debug assertions are enabled, which means there is no panic by default in release mode. One may wonder whether other bad things happen in release mode though, since in that case, the arithmetic will wrap around instead. Since this is in new code and since the regex crate doesn't yet utilize the min/max attributes of an Hir, the wrap around in this case is completely innocuous. Fixes #995
1 parent 65ec58c commit 841022a

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

regex-syntax/src/hir/mod.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -2481,16 +2481,24 @@ impl Properties {
24812481
props.literal = props.literal && p.is_literal();
24822482
props.alternation_literal =
24832483
props.alternation_literal && p.is_alternation_literal();
2484-
if let Some(ref mut minimum_len) = props.minimum_len {
2484+
if let Some(minimum_len) = props.minimum_len {
24852485
match p.minimum_len() {
24862486
None => props.minimum_len = None,
2487-
Some(len) => *minimum_len += len,
2487+
Some(len) => {
2488+
// We use saturating arithmetic here because the
2489+
// minimum is just a lower bound. We can't go any
2490+
// higher than what our number types permit.
2491+
props.minimum_len =
2492+
Some(minimum_len.saturating_add(len));
2493+
}
24882494
}
24892495
}
2490-
if let Some(ref mut maximum_len) = props.maximum_len {
2496+
if let Some(maximum_len) = props.maximum_len {
24912497
match p.maximum_len() {
24922498
None => props.maximum_len = None,
2493-
Some(len) => *maximum_len += len,
2499+
Some(len) => {
2500+
props.maximum_len = maximum_len.checked_add(len)
2501+
}
24942502
}
24952503
}
24962504
}

tests/regression.rs

+8
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,11 @@ fn regression_unicode_perl_not_enabled() {
240240
let re = regex_new!(pat);
241241
assert!(re.is_ok());
242242
}
243+
244+
// See: https://github.com/rust-lang/regex/issues/995
245+
#[test]
246+
fn regression_big_regex_overflow() {
247+
let pat = r" {2147483516}{2147483416}{5}";
248+
let re = regex_new!(pat);
249+
assert!(re.is_err());
250+
}

0 commit comments

Comments
 (0)