You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
safety: guard in Input::new against incorrect AsRef implementations
Before this commit, Input::new calls haystack.as_ref() twice, once to
get the actual haystack slice and the second time to get its length. It
makes the assumption that the second call will return the same slice,
but malicious implementations of AsRef can return different slices
and thus different lengths. This is important because there's unsafe
code relying on the Input's span being inbounds with respect to the
haystack, but if the second call to .as_ref() returns a bigger slice
this won't be true.
For example, this snippet causes Miri to report UB on an unchecked
slice access in find_fwd_imp (though it will also panic sometime later
when run normally, but at that point the UB already happened):
use regex_automata::{Input, meta::{Builder, Config}};
use std::cell::Cell;
struct Bad(Cell<bool>);
impl AsRef<[u8]> for Bad {
fn as_ref(&self) -> &[u8] {
if self.0.replace(false) {
&[]
} else {
&[0; 1000]
}
}
}
let bad = Bad(Cell::new(true));
let input = Input::new(&bad);
let regex = Builder::new()
// Not setting this causes some checked access to occur before
// the unchecked ones, avoiding the UB
.configure(Config::new().auto_prefilter(false))
.build("a+")
.unwrap();
regex.find(input);
This commit fixes the problem by just calling .as_ref() once and use
the length of the returned slice as the span's end value. A regression
test has also been added.
Closes#1154
0 commit comments