diff --git a/CHANGELOG.md b/CHANGELOG.md index 38da512ed..527950518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,14 @@ 1.10.3 (TBD) ============ This is a new patch release that fixes the feature configuration of optional -dependencies. +dependencies, and fixes an unsound use of bounds check elision. Bug fixes: * [BUG #1147](https://github.com/rust-lang/regex/issues/1147): Set `default-features=false` for the `memchr` and `aho-corasick` dependencies. +* [BUG #1154](https://github.com/rust-lang/regex/pull/1154): +Fix unsound bounds check elision. 1.10.2 (2023-10-16) diff --git a/regex-automata/src/util/search.rs b/regex-automata/src/util/search.rs index 39aec522b..05b1cff54 100644 --- a/regex-automata/src/util/search.rs +++ b/regex-automata/src/util/search.rs @@ -110,9 +110,14 @@ impl<'h> Input<'h> { /// Create a new search configuration for the given haystack. #[inline] pub fn new>(haystack: &'h H) -> Input<'h> { + // Perform only one call to `haystack.as_ref()` to protect from incorrect + // implementations that return different values from multiple calls. + // This is important because there's code that relies on `span` not being + // out of bounds with respect to the stored `haystack`. + let haystack = haystack.as_ref(); Input { - haystack: haystack.as_ref(), - span: Span { start: 0, end: haystack.as_ref().len() }, + haystack, + span: Span { start: 0, end: haystack.len() }, anchored: Anchored::No, earliest: false, } @@ -1966,4 +1971,23 @@ mod tests { let expected_size = 3 * core::mem::size_of::(); assert_eq!(expected_size, core::mem::size_of::()); } + + #[test] + fn incorrect_asref_guard() { + struct Bad(std::cell::Cell); + + impl AsRef<[u8]> for Bad { + fn as_ref(&self) -> &[u8] { + if self.0.replace(false) { + &[] + } else { + &[0; 1000] + } + } + } + + let bad = Bad(std::cell::Cell::new(true)); + let input = Input::new(&bad); + assert!(input.end() <= input.haystack().len()); + } }