Use memmem for finding needle in haystack

This commit is contained in:
topjohnwu 2024-04-10 14:57:44 -07:00
parent ffc1e38e48
commit c50ee722a1
2 changed files with 33 additions and 4 deletions

View File

@ -78,11 +78,40 @@ impl<T> LibcReturn for *mut T {
} }
} }
pub trait BytesExt {
fn find(&self, needle: &[u8]) -> Option<usize>;
fn contains(&self, needle: &[u8]) -> bool {
self.find(needle).is_some()
}
}
impl<T: AsRef<[u8]> + ?Sized> BytesExt for T {
fn find(&self, needle: &[u8]) -> Option<usize> {
fn inner(haystack: &[u8], needle: &[u8]) -> Option<usize> {
unsafe {
let ptr: *const u8 = libc::memmem(
haystack.as_ptr().cast(),
haystack.len(),
needle.as_ptr().cast(),
needle.len(),
)
.cast();
if ptr.is_null() {
None
} else {
Some(ptr.offset_from(haystack.as_ptr()) as usize)
}
}
}
inner(self.as_ref(), needle)
}
}
pub trait MutBytesExt { pub trait MutBytesExt {
fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec<usize>; fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec<usize>;
} }
impl<T: AsMut<[u8]>> MutBytesExt for T { impl<T: AsMut<[u8]> + ?Sized> MutBytesExt for T {
fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec<usize> { fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec<usize> {
ffi::mut_u8_patch(self.as_mut(), from, to) ffi::mut_u8_patch(self.as_mut(), from, to)
} }

View File

@ -21,8 +21,8 @@ use base::libc::{
S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR,
}; };
use base::{ use base::{
log_err, map_args, EarlyExitExt, FsPath, LoggedResult, MappedFile, ResultExt, Utf8CStr, log_err, map_args, BytesExt, EarlyExitExt, FsPath, LoggedResult, MappedFile, ResultExt,
WriteExt, Utf8CStr, WriteExt,
}; };
use crate::ffi::{unxz, xz}; use crate::ffi::{unxz, xz};
@ -246,7 +246,7 @@ impl Cpio {
continue; continue;
} }
if name == "TRAILER!!!" { if name == "TRAILER!!!" {
match data[pos..].windows(6).position(|x| x == b"070701") { match data[pos..].find(b"070701") {
Some(x) => pos += x, Some(x) => pos += x,
None => break, None => break,
} }