1
1
// Original implementation taken from rust-memchr.
2
2
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
3
3
4
- // ignore-tidy-undocumented-unsafe
5
-
6
4
use crate :: cmp;
7
5
use crate :: mem;
8
6
@@ -72,6 +70,8 @@ fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
72
70
// search the body of the text
73
71
let repeated_x = repeat_byte ( x) ;
74
72
while offset <= len - 2 * USIZE_BYTES {
73
+ // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes
74
+ // between the offset and the end of the slice.
75
75
unsafe {
76
76
let u = * ( ptr. add ( offset) as * const usize ) ;
77
77
let v = * ( ptr. add ( offset + USIZE_BYTES ) as * const usize ) ;
@@ -105,6 +105,8 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
105
105
let ( min_aligned_offset, max_aligned_offset) = {
106
106
// We call this just to obtain the length of the prefix and suffix.
107
107
// In the middle we always process two chunks at once.
108
+ // SAFETY: transmuting `[u8]` to `[usize]` is safe except for size differences
109
+ // which are handled by `align_to`.
108
110
let ( prefix, _, suffix) = unsafe { text. align_to :: < ( Chunk , Chunk ) > ( ) } ;
109
111
( prefix. len ( ) , len - suffix. len ( ) )
110
112
} ;
@@ -121,6 +123,8 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
121
123
let chunk_bytes = mem:: size_of :: < Chunk > ( ) ;
122
124
123
125
while offset > min_aligned_offset {
126
+ // SAFETY: offset starts at len - suffix.len(), as long as it is greater than
127
+ // min_aligned_offset (prefix.len()) the remaining distance is at least 2 * chunk_bytes.
124
128
unsafe {
125
129
let u = * ( ptr. offset ( offset as isize - 2 * chunk_bytes as isize ) as * const Chunk ) ;
126
130
let v = * ( ptr. offset ( offset as isize - chunk_bytes as isize ) as * const Chunk ) ;
0 commit comments