From a3aa0e90820cfdad70be962d872ba2f4c86a1309 Mon Sep 17 00:00:00 2001 From: moonheart08 Date: Tue, 8 Sep 2020 13:08:35 -0500 Subject: [PATCH] Document safety in memchr, remove unsafe. Documents the safety of two unsafe blocks and removes an unnecessary one --- library/core/src/slice/memchr.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 3b13ed5fed396..a9994d901272e 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -1,8 +1,6 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch -// ignore-tidy-undocumented-unsafe - use crate::cmp; use crate::mem; @@ -63,6 +61,8 @@ pub fn memchr(x: u8, text: &[u8]) -> Option { if len >= 2 * usize_bytes { while offset <= len - 2 * usize_bytes { + // SAFETY: offset + usize_bytes will never be out of bounds due to the bounds check above. + // All indexing is in range aligned_boundary to len - 2 * size_of::() unsafe { let u = *(ptr.add(offset) as *const usize); let v = *(ptr.add(offset + usize_bytes) as *const usize); @@ -97,8 +97,13 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { let (min_aligned_offset, max_aligned_offset) = { // We call this just to obtain the length of the prefix and suffix. // In the middle we always process two chunks at once. - let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() }; - (prefix.len(), len - suffix.len()) + let offset = ptr.align_offset(mem::align_of::<(Chunk, Chunk)>()); + if offset > len { + (len, 0) + } else { + let (lower, rest) = text.split_at(offset); + (lower.len(), len - rest.align_to_offsets::<(Chunk, Chunk)>().1) + } }; let mut offset = max_aligned_offset; @@ -113,6 +118,8 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { let chunk_bytes = mem::size_of::(); while offset > min_aligned_offset { + // SAFETY: offset will never be less than zero, guarenteed by the alignment check. + // All indexing is in range max_aligned_offset to min_aligned_offset. unsafe { let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk); let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk);