From c50ee722a133ac2011242a888b533844c9400ad2 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 10 Apr 2024 14:57:44 -0700 Subject: [PATCH] Use memmem for finding needle in haystack --- native/src/base/misc.rs | 31 ++++++++++++++++++++++++++++++- native/src/boot/cpio.rs | 6 +++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/native/src/base/misc.rs b/native/src/base/misc.rs index ff9d1dfd0..5413ffe92 100644 --- a/native/src/base/misc.rs +++ b/native/src/base/misc.rs @@ -78,11 +78,40 @@ impl LibcReturn for *mut T { } } +pub trait BytesExt { + fn find(&self, needle: &[u8]) -> Option; + fn contains(&self, needle: &[u8]) -> bool { + self.find(needle).is_some() + } +} + +impl + ?Sized> BytesExt for T { + fn find(&self, needle: &[u8]) -> Option { + fn inner(haystack: &[u8], needle: &[u8]) -> Option { + 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 { fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec; } -impl> MutBytesExt for T { +impl + ?Sized> MutBytesExt for T { fn patch(&mut self, from: &[u8], to: &[u8]) -> Vec { ffi::mut_u8_patch(self.as_mut(), from, to) } diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index d622e76b9..432161d38 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -21,8 +21,8 @@ use base::libc::{ S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, }; use base::{ - log_err, map_args, EarlyExitExt, FsPath, LoggedResult, MappedFile, ResultExt, Utf8CStr, - WriteExt, + log_err, map_args, BytesExt, EarlyExitExt, FsPath, LoggedResult, MappedFile, ResultExt, + Utf8CStr, WriteExt, }; use crate::ffi::{unxz, xz}; @@ -246,7 +246,7 @@ impl Cpio { continue; } if name == "TRAILER!!!" { - match data[pos..].windows(6).position(|x| x == b"070701") { + match data[pos..].find(b"070701") { Some(x) => pos += x, None => break, }