From 70b9575cc580cf46136874faf32bbb396db1f7c0 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Thu, 18 May 2023 09:55:09 -0400 Subject: [PATCH] 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 --- regex-syntax/src/hir/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/regex-syntax/src/hir/mod.rs b/regex-syntax/src/hir/mod.rs index e5ea3701b..062d4dcab 100644 --- a/regex-syntax/src/hir/mod.rs +++ b/regex-syntax/src/hir/mod.rs @@ -2481,16 +2481,24 @@ impl Properties { props.literal = props.literal && p.is_literal(); props.alternation_literal = props.alternation_literal && p.is_alternation_literal(); - if let Some(ref mut minimum_len) = props.minimum_len { + if let Some(minimum_len) = props.minimum_len { match p.minimum_len() { None => props.minimum_len = None, - Some(len) => *minimum_len += len, + Some(len) => { + // We use saturating arithmetic here because the + // minimum is just a lower bound. We can't go any + // higher than what our number types permit. + props.minimum_len = + Some(minimum_len.saturating_add(len)); + } } } - if let Some(ref mut maximum_len) = props.maximum_len { + if let Some(maximum_len) = props.maximum_len { match p.maximum_len() { None => props.maximum_len = None, - Some(len) => *maximum_len += len, + Some(len) => { + props.maximum_len = maximum_len.checked_add(len) + } } } }