diff --git a/gix-bitmap/src/ewah.rs b/gix-bitmap/src/ewah.rs index 37a5eb34367..c9599be313e 100644 --- a/gix-bitmap/src/ewah.rs +++ b/gix-bitmap/src/ewah.rs @@ -25,9 +25,11 @@ pub fn decode(data: &[u8]) -> Result<(Vec, &[u8]), decode::Error> { // NOTE: git does this by copying all bytes first, and then it will change the endianness in a separate loop. // Maybe it's faster, but we can't do it without unsafe. Let's leave it to the optimizer and maybe // one day somebody will find out that it's worth it to use unsafe here. - let (mut bits, data) = decode::split_at_pos(data, len * std::mem::size_of::()).ok_or(Error::Corrupt { - message: "eof while reading bit data", - })?; + let (mut bits, data) = data + .split_at_checked(len * std::mem::size_of::()) + .ok_or(Error::Corrupt { + message: "eof while reading bit data", + })?; let mut buf = std::vec::Vec::::with_capacity(len); for _ in 0..len { let (bit_num, rest) = bits.split_at(std::mem::size_of::()); diff --git a/gix-bitmap/src/lib.rs b/gix-bitmap/src/lib.rs index 0ccc5824843..d5c41ea2908 100644 --- a/gix-bitmap/src/lib.rs +++ b/gix-bitmap/src/lib.rs @@ -7,16 +7,9 @@ pub mod ewah; pub(crate) mod decode { - #[inline] - pub(crate) fn split_at_pos(data: &[u8], pos: usize) -> Option<(&[u8], &[u8])> { - if data.len() < pos { - return None; - } - data.split_at(pos).into() - } - #[inline] pub(crate) fn u32(data: &[u8]) -> Option<(u32, &[u8])> { - split_at_pos(data, 4).map(|(num, data)| (u32::from_be_bytes(num.try_into().unwrap()), data)) + data.split_at_checked(4) + .map(|(num, data)| (u32::from_be_bytes(num.try_into().unwrap()), data)) } } diff --git a/gix-index/src/decode/entries.rs b/gix-index/src/decode/entries.rs index f32074208f5..a32cb3ff6a6 100644 --- a/gix-index/src/decode/entries.rs +++ b/gix-index/src/decode/entries.rs @@ -3,7 +3,7 @@ use std::ops::Range; use crate::{ decode::{self, header}, entry, - util::{read_u32, split_at_byte_exclusive, split_at_pos, var_int}, + util::{read_u32, split_at_byte_exclusive, var_int}, Entry, Version, }; @@ -94,7 +94,7 @@ fn load_one<'a>( let (uid, data) = read_u32(data)?; let (gid, data) = read_u32(data)?; let (size, data) = read_u32(data)?; - let (hash, data) = split_at_pos(data, hash_len)?; + let (hash, data) = data.split_at_checked(hash_len)?; let (flags, data) = read_u16(data)?; let flags = entry::at_rest::Flags::from_bits_retain(flags); let (flags, data) = if flags.contains(entry::at_rest::Flags::EXTENDED) { @@ -128,7 +128,7 @@ fn load_one<'a>( split_at_byte_exclusive(data, 0)? } else { let path_len = (flags.bits() & entry::Flags::PATH_LEN.bits()) as usize; - let (path, data) = split_at_pos(data, path_len)?; + let (path, data) = data.split_at_checked(path_len)?; (path, skip_padding(data, first_byte_of_entry)) }; @@ -177,5 +177,6 @@ fn skip_padding(data: &[u8], first_byte_of_entry: usize) -> &[u8] { #[inline] fn read_u16(data: &[u8]) -> Option<(u16, &[u8])> { - split_at_pos(data, 2).map(|(num, data)| (u16::from_be_bytes(num.try_into().unwrap()), data)) + data.split_at_checked(2) + .map(|(num, data)| (u16::from_be_bytes(num.try_into().unwrap()), data)) } diff --git a/gix-index/src/extension/link.rs b/gix-index/src/extension/link.rs index 722cbd17971..de64e659689 100644 --- a/gix-index/src/extension/link.rs +++ b/gix-index/src/extension/link.rs @@ -1,7 +1,4 @@ -use crate::{ - extension::{Link, Signature}, - util::split_at_pos, -}; +use crate::extension::{Link, Signature}; /// The signature of the link extension. pub const SIGNATURE: Signature = *b"link"; @@ -39,7 +36,8 @@ pub mod decode { } pub(crate) fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Result { - let (id, data) = split_at_pos(data, object_hash.len_in_bytes()) + let (id, data) = data + .split_at_checked(object_hash.len_in_bytes()) .ok_or(decode::Error::Corrupt( "link extension too short to read share index checksum", )) diff --git a/gix-index/src/extension/resolve_undo.rs b/gix-index/src/extension/resolve_undo.rs index 932228f2c83..37c9333f944 100644 --- a/gix-index/src/extension/resolve_undo.rs +++ b/gix-index/src/extension/resolve_undo.rs @@ -1,10 +1,7 @@ use bstr::BString; use gix_hash::ObjectId; -use crate::{ - extension::Signature, - util::{split_at_byte_exclusive, split_at_pos}, -}; +use crate::{extension::Signature, util::split_at_byte_exclusive}; pub type Paths = Vec; @@ -47,7 +44,7 @@ pub fn decode(mut data: &[u8], object_hash: gix_hash::Kind) -> Option { if *mode == 0 { continue; } - let (hash, rest) = split_at_pos(data, hash_len)?; + let (hash, rest) = data.split_at_checked(hash_len)?; data = rest; *stage = Some(Stage { mode: *mode, diff --git a/gix-index/src/extension/tree/decode.rs b/gix-index/src/extension/tree/decode.rs index 71e881ac38a..e3449ec6ae7 100644 --- a/gix-index/src/extension/tree/decode.rs +++ b/gix-index/src/extension/tree/decode.rs @@ -1,9 +1,6 @@ use gix_hash::ObjectId; -use crate::{ - extension::Tree, - util::{split_at_byte_exclusive, split_at_pos}, -}; +use crate::{extension::Tree, util::split_at_byte_exclusive}; /// A recursive data structure pub fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Option { @@ -26,7 +23,7 @@ fn one_recursive(data: &[u8], hash_len: usize) -> Option<(Tree, &[u8])> { let subtree_count: usize = gix_utils::btoi::to_unsigned(subtree_count).ok()?; let (id, mut data) = if num_entries >= 0 { - let (hash, data) = split_at_pos(data, hash_len)?; + let (hash, data) = data.split_at_checked(hash_len)?; (ObjectId::from_bytes_or_panic(hash), data) } else { ( diff --git a/gix-index/src/extension/untracked_cache.rs b/gix-index/src/extension/untracked_cache.rs index 5a875657ba8..6da198c4479 100644 --- a/gix-index/src/extension/untracked_cache.rs +++ b/gix-index/src/extension/untracked_cache.rs @@ -4,7 +4,7 @@ use gix_hash::ObjectId; use crate::{ entry, extension::{Signature, UntrackedCache}, - util::{read_u32, split_at_byte_exclusive, split_at_pos, var_int}, + util::{read_u32, split_at_byte_exclusive, var_int}, }; /// A structure to track filesystem stat information along with an object id, linking a worktree file with what's in our ODB. @@ -44,7 +44,7 @@ pub fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Option Option(data: &'a [u8], directories: &mut Vec) fn decode_oid_stat(data: &[u8], hash_len: usize) -> Option<(OidStat, &[u8])> { let (stat, data) = crate::decode::stat(data)?; - let (hash, data) = split_at_pos(data, hash_len)?; + let (hash, data) = data.split_at_checked(hash_len)?; Some(( OidStat { stat, diff --git a/gix-index/src/lib.rs b/gix-index/src/lib.rs index ffc0afc4724..344af7f81eb 100644 --- a/gix-index/src/lib.rs +++ b/gix-index/src/lib.rs @@ -198,12 +198,14 @@ pub(crate) mod util { #[inline] pub fn read_u32(data: &[u8]) -> Option<(u32, &[u8])> { - split_at_pos(data, 4).map(|(num, data)| (u32::from_be_bytes(num.try_into().unwrap()), data)) + data.split_at_checked(4) + .map(|(num, data)| (u32::from_be_bytes(num.try_into().unwrap()), data)) } #[inline] pub fn read_u64(data: &[u8]) -> Option<(u64, &[u8])> { - split_at_pos(data, 8).map(|(num, data)| (u64::from_be_bytes(num.try_into().unwrap()), data)) + data.split_at_checked(8) + .map(|(num, data)| (u64::from_be_bytes(num.try_into().unwrap()), data)) } #[inline] @@ -227,12 +229,4 @@ pub(crate) mod util { }) }) } - - #[inline] - pub fn split_at_pos(data: &[u8], pos: usize) -> Option<(&[u8], &[u8])> { - if data.len() < pos { - return None; - } - data.split_at(pos).into() - } }