|
2 | 2 |
|
3 | 3 | use alloc::vec::{self, Vec};
|
4 | 4 | use core::{
|
5 |
| - cmp::{min, Ordering}, |
6 |
| - ops::{Bound, Range, RangeBounds}, |
| 5 | + cmp::Ordering, |
| 6 | + ops::{Range, RangeBounds}, |
7 | 7 | };
|
8 | 8 |
|
9 | 9 | use libafl_bolts::{
|
10 |
| - ownedref::{OwnedMutSlice, OwnedSlice}, |
| 10 | + subrange::{end_index, start_index, sub_range}, |
11 | 11 | HasLen,
|
12 | 12 | };
|
13 | 13 |
|
14 | 14 | use crate::inputs::HasMutatorBytes;
|
15 | 15 |
|
16 |
| -/// Gets the relevant concrete start index from [`RangeBounds`] (inclusive) |
17 |
| -fn start_index<R>(range: &R) -> usize |
18 |
| -where |
19 |
| - R: RangeBounds<usize>, |
20 |
| -{ |
21 |
| - match range.start_bound() { |
22 |
| - Bound::Unbounded => 0, |
23 |
| - Bound::Included(start) => *start, |
24 |
| - Bound::Excluded(start) => start + 1, |
25 |
| - } |
26 |
| -} |
27 |
| - |
28 |
| -/// Gets the relevant concrete end index from [`RangeBounds`] (exclusive) |
29 |
| -fn end_index<R>(range: &R, max_len: usize) -> usize |
30 |
| -where |
31 |
| - R: RangeBounds<usize>, |
32 |
| -{ |
33 |
| - let end = match range.end_bound() { |
34 |
| - Bound::Unbounded => max_len, |
35 |
| - Bound::Included(end) => end + 1, |
36 |
| - Bound::Excluded(end) => *end, |
37 |
| - }; |
38 |
| - |
39 |
| - min(end, max_len) |
40 |
| -} |
41 |
| - |
42 |
| -fn sub_range<R>(outer_range: &Range<usize>, inner_range: R) -> (Bound<usize>, Bound<usize>) |
43 |
| -where |
44 |
| - R: RangeBounds<usize>, |
45 |
| -{ |
46 |
| - let start = |
47 |
| - match (outer_range.start_bound(), inner_range.start_bound()) { |
48 |
| - (Bound::Unbounded, Bound::Unbounded) => Bound::Unbounded, |
49 |
| - (Bound::Excluded(bound), Bound::Unbounded) |
50 |
| - | (Bound::Unbounded, Bound::Excluded(bound)) => Bound::Excluded(*bound), |
51 |
| - (Bound::Included(bound), Bound::Unbounded) |
52 |
| - | (Bound::Unbounded, Bound::Included(bound)) => Bound::Included(*bound), |
53 |
| - (Bound::Included(own), Bound::Included(other)) => Bound::Included(own + other), |
54 |
| - (Bound::Included(own), Bound::Excluded(other)) |
55 |
| - | (Bound::Excluded(own), Bound::Included(other)) => Bound::Excluded(own + other), |
56 |
| - (Bound::Excluded(own), Bound::Excluded(other)) => Bound::Excluded(own + other + 1), |
57 |
| - }; |
58 |
| - |
59 |
| - let end = match (outer_range.end_bound(), inner_range.end_bound()) { |
60 |
| - (Bound::Unbounded, Bound::Unbounded) => Bound::Unbounded, |
61 |
| - (Bound::Excluded(bound), Bound::Unbounded) => Bound::Excluded(*bound), |
62 |
| - (Bound::Unbounded, Bound::Excluded(bound)) => Bound::Excluded(outer_range.end - *bound), |
63 |
| - (Bound::Included(bound), Bound::Unbounded) => Bound::Included(*bound), |
64 |
| - (Bound::Unbounded, Bound::Included(bound)) => Bound::Included(outer_range.end - *bound), |
65 |
| - (Bound::Included(own), Bound::Included(other)) => { |
66 |
| - Bound::Included(min(*own, outer_range.start + other)) |
67 |
| - } |
68 |
| - (Bound::Included(own), Bound::Excluded(other)) => { |
69 |
| - Bound::Included(min(*own, outer_range.start + other - 1)) |
70 |
| - } |
71 |
| - (Bound::Excluded(own), Bound::Included(other)) => { |
72 |
| - Bound::Included(min(*own - 1, outer_range.start + other)) |
73 |
| - } |
74 |
| - (Bound::Excluded(own), Bound::Excluded(other)) => { |
75 |
| - Bound::Excluded(min(*own, outer_range.start + other)) |
76 |
| - } |
77 |
| - }; |
78 |
| - |
79 |
| - (start, end) |
80 |
| -} |
81 |
| - |
82 |
| -/// An immutable contiguous subslice of a byte slice. |
83 |
| -/// It is mostly useful to cheaply wrap a subslice of a given input. |
84 |
| -/// |
85 |
| -/// A mutable version is available: [`BytesSliceMut`]. |
86 |
| -#[derive(Debug)] |
87 |
| -pub struct BytesSlice<'a> { |
88 |
| - /// The (complete) parent input we will work on |
89 |
| - parent_slice: OwnedSlice<'a, u8>, |
90 |
| - /// The range inside the parent input we will work on |
91 |
| - range: Range<usize>, |
92 |
| -} |
93 |
| - |
94 |
| -impl<'a> HasLen for BytesSlice<'a> { |
95 |
| - #[inline] |
96 |
| - fn len(&self) -> usize { |
97 |
| - self.range.len() |
98 |
| - } |
99 |
| -} |
100 |
| - |
101 |
| -impl<'a> BytesSlice<'a> { |
102 |
| - /// Creates a new [`BytesSlice`], a sub-slice representation of a byte array. |
103 |
| - pub fn new<R>(parent_slice: OwnedSlice<'a, u8>, range: R) -> Self |
104 |
| - where |
105 |
| - R: RangeBounds<usize>, |
106 |
| - { |
107 |
| - let parent_len = parent_slice.len(); |
108 |
| - |
109 |
| - BytesSlice { |
110 |
| - parent_slice, |
111 |
| - range: Range { |
112 |
| - start: start_index(&range), |
113 |
| - end: end_index(&range, parent_len), |
114 |
| - }, |
115 |
| - } |
116 |
| - } |
117 |
| - |
118 |
| - /// Get the sub slice as bytes. |
119 |
| - #[must_use] |
120 |
| - pub fn bytes(&self) -> &[u8] { |
121 |
| - &self.parent_slice[self.range.clone()] |
122 |
| - } |
123 |
| - |
124 |
| - /// Creates a new [`BytesSlice`] that's a sliced view on a bytes slice. |
125 |
| - pub fn with_slice<R>(parent_slice: &'a [u8], range: R) -> Self |
126 |
| - where |
127 |
| - R: RangeBounds<usize>, |
128 |
| - { |
129 |
| - Self::new(parent_slice.into(), range) |
130 |
| - } |
131 |
| - |
132 |
| - /// The parent input |
133 |
| - #[must_use] |
134 |
| - pub fn parent_slice(self) -> OwnedSlice<'a, u8> { |
135 |
| - self.parent_slice |
136 |
| - } |
137 |
| - |
138 |
| - /// The inclusive start index in the parent buffer |
139 |
| - #[must_use] |
140 |
| - pub fn start_index(&self) -> usize { |
141 |
| - self.range.start |
142 |
| - } |
143 |
| - |
144 |
| - /// The exclusive end index in the parent buffer |
145 |
| - #[must_use] |
146 |
| - pub fn end_index(&self) -> usize { |
147 |
| - self.range.end |
148 |
| - } |
149 |
| - |
150 |
| - /// Creates a sub range in the current own range |
151 |
| - pub fn sub_range<R>(&self, range: R) -> (Bound<usize>, Bound<usize>) |
152 |
| - where |
153 |
| - R: RangeBounds<usize>, |
154 |
| - { |
155 |
| - sub_range(&self.range, range) |
156 |
| - } |
157 |
| -} |
158 |
| - |
159 |
| -/// A mutable contiguous subslice of a byte slice. |
160 |
| -/// It is mostly useful to cheaply wrap a subslice of a given input. |
161 |
| -/// |
162 |
| -/// An immutable version is available: [`BytesSlice`]. |
163 |
| -#[derive(Debug)] |
164 |
| -pub struct BytesSliceMut<'a> { |
165 |
| - /// The (complete) parent input we will work on |
166 |
| - parent_slice: OwnedMutSlice<'a, u8>, |
167 |
| - /// The range inside the parent input we will work on |
168 |
| - range: Range<usize>, |
169 |
| -} |
170 |
| - |
171 |
| -impl<'a> BytesSliceMut<'a> { |
172 |
| - /// Creates a new [`BytesSliceMut`], a sub-slice representation of a byte array. |
173 |
| - pub fn new<R>(parent_slice: OwnedMutSlice<'a, u8>, range: R) -> Self |
174 |
| - where |
175 |
| - R: RangeBounds<usize>, |
176 |
| - { |
177 |
| - let parent_len = parent_slice.len(); |
178 |
| - |
179 |
| - BytesSliceMut { |
180 |
| - parent_slice, |
181 |
| - range: Range { |
182 |
| - start: start_index(&range), |
183 |
| - end: end_index(&range, parent_len), |
184 |
| - }, |
185 |
| - } |
186 |
| - } |
187 |
| - |
188 |
| - /// Get the sub slice as bytes. |
189 |
| - #[must_use] |
190 |
| - pub fn bytes(&self) -> &[u8] { |
191 |
| - &self.parent_slice[self.range.clone()] |
192 |
| - } |
193 |
| - |
194 |
| - /// Get the sub slice as bytes. |
195 |
| - #[must_use] |
196 |
| - pub fn bytes_mut(&mut self) -> &mut [u8] { |
197 |
| - &mut self.parent_slice[self.range.clone()] |
198 |
| - } |
199 |
| - |
200 |
| - /// Creates a new [`BytesSliceMut`] that's a view on a bytes slice. |
201 |
| - /// The sub-slice can then be used to mutate parts of the original bytes. |
202 |
| - pub fn with_slice<R>(parent_slice: &'a mut [u8], range: R) -> Self |
203 |
| - where |
204 |
| - R: RangeBounds<usize>, |
205 |
| - { |
206 |
| - Self::new(parent_slice.into(), range) |
207 |
| - } |
208 |
| - |
209 |
| - /// The parent input |
210 |
| - #[must_use] |
211 |
| - pub fn parent_slice(self) -> OwnedMutSlice<'a, u8> { |
212 |
| - self.parent_slice |
213 |
| - } |
214 |
| - |
215 |
| - /// The inclusive start index in the parent buffer |
216 |
| - #[must_use] |
217 |
| - pub fn start_index(&self) -> usize { |
218 |
| - self.range.start |
219 |
| - } |
220 |
| - |
221 |
| - /// The exclusive end index in the parent buffer |
222 |
| - #[must_use] |
223 |
| - pub fn end_index(&self) -> usize { |
224 |
| - self.range.end |
225 |
| - } |
226 |
| - |
227 |
| - /// Creates a sub range in the current own range |
228 |
| - pub fn sub_range<R>(&self, range: R) -> (Bound<usize>, Bound<usize>) |
229 |
| - where |
230 |
| - R: RangeBounds<usize>, |
231 |
| - { |
232 |
| - sub_range(&self.range, range) |
233 |
| - } |
234 |
| -} |
235 |
| - |
236 |
| -impl<'a> HasLen for BytesSliceMut<'a> { |
237 |
| - #[inline] |
238 |
| - fn len(&self) -> usize { |
239 |
| - self.range.len() |
240 |
| - } |
241 |
| -} |
242 |
| - |
243 | 16 | /// The [`BytesSubInput`] makes it possible to use [`crate::mutators::Mutator`]`s` that work on
|
244 | 17 | /// inputs implementing the [`HasMutatorBytes`] for a sub-range of this input.
|
245 | 18 | /// For example, we can do the following:
|
|
0 commit comments