Skip to content

Commit 97d8d11

Browse files
sharksforarmsBurntSushi
authored andcommitted
bug: ensure FFI glue always passes a valid pointer
Previously, if a caller provided a `&Vec::new()` to the search function, then the library would pass that vec's pointer to PCRE2 directly. Since creating an empty Vec does not allocate, this pointer is actually invalid and cannot be dereferenced. However, PCRE2 (rightfully) assumes the pointer it is handed is valid. We fix this by detecting the case of an empty slice. If it's empty, we pass a pointer to an empty slice that we know is valid.
1 parent a62c798 commit 97d8d11

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/bytes.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,19 @@ mod tests {
12591259
assert!(re.is_match(b("a")).unwrap());
12601260
}
12611261

1262+
// This tests a regression caused a segfault in the pcre2 library
1263+
// https://github.com/BurntSushi/rust-pcre2/issues/10
1264+
#[test]
1265+
fn jit_test_lazy_alloc_subject() {
1266+
let subject: Vec<u8> = vec![];
1267+
1268+
let re = RegexBuilder::new()
1269+
.jit_if_available(true)
1270+
.build(r"xxxx|xxxx|xxxx")
1271+
.unwrap();
1272+
assert!(!re.is_match(&subject).unwrap());
1273+
}
1274+
12621275
#[test]
12631276
fn utf_with_invalid_data() {
12641277
let re = RegexBuilder::new()

src/ffi.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,20 @@ impl MatchData {
402402
pub unsafe fn find(
403403
&mut self,
404404
code: &Code,
405-
subject: &[u8],
405+
mut subject: &[u8],
406406
start: usize,
407407
options: u32,
408408
) -> Result<bool, Error> {
409+
// When the subject is empty, we use an empty slice
410+
// with a known valid pointer. Otherwise, slices derived
411+
// from, e.g., an empty `Vec<u8>` may not have a valid
412+
// pointer, since creating an empty `Vec` is guaranteed
413+
// to not allocate.
414+
const EMPTY: &[u8] = &[];
415+
if subject.is_empty() {
416+
subject = EMPTY;
417+
}
418+
409419
let rc = pcre2_match_8(
410420
code.as_ptr(),
411421
subject.as_ptr(),

0 commit comments

Comments
 (0)