1use crate::mutator::Mutator;
2use crate::rand::seq::index;
3use crate::rand::Rng;
4use crate::traits::*;
5use crate::types::*;
6use crate::NewFuzzed;
7
8use num_traits::{Bounded, NumCast};
9use num_traits::{WrappingAdd, WrappingSub};
10use std::cmp::min;
11use std::ops::BitXor;
12
13#[derive(Copy, Clone, NewFuzzed, PartialEq)]
15enum VecResizeCount {
16 Quarter,
17 Half,
18 ThreeQuarters,
19 FixedBytes,
20 AllBytes,
21}
22
23#[derive(Copy, Clone, NewFuzzed)]
24enum VecResizeDirection {
25 FromBeginning,
26 FromEnd,
27}
28
29#[derive(Copy, Clone, PartialEq, NewFuzzed)]
30enum VecResizeType {
31 Grow,
32 Shrink,
33}
34
35fn grow_vec<T: NewFuzzed + SerializedSize, R: Rng>(
39 vec: &mut Vec<T>,
40 mutator: &mut Mutator<R>,
41 mut max_size: Option<usize>,
42) {
43 let resize_count = VecResizeCount::new_fuzzed(mutator, None);
44 let mut num_elements = if vec.is_empty() {
45 mutator.gen_range(1, 9)
46 } else {
47 match resize_count {
48 VecResizeCount::Quarter => vec.len() / 4,
49 VecResizeCount::Half => vec.len() / 2,
50 VecResizeCount::ThreeQuarters => vec.len() - (vec.len() / 4),
51 VecResizeCount::FixedBytes => mutator.gen_range(1, 9),
52 VecResizeCount::AllBytes => {
53 mutator.gen_range(1, vec.len() + 1)
54 }
55 }
56 };
57
58 if let Some(max_size) = max_size.clone() {
60 num_elements = min(num_elements, max_size / T::max_default_object_size());
61 }
62
63 if num_elements == 0 {
64 return;
65 }
66
67 match VecResizeDirection::new_fuzzed(mutator, None) {
68 VecResizeDirection::FromBeginning => {
69 let mut new_vec = Vec::with_capacity(num_elements);
72 for _i in 0..num_elements {
73 let constraints = max_size.map(|max_size| {
74 let mut c = Constraints::new();
75 c.max_size(max_size);
76 c.base_object_size_accounted_for = true;
77
78 c
79 });
80
81 let element = T::new_fuzzed(mutator, constraints.as_ref());
82 if let Some(inner_max_size) = max_size {
83 let element_size = element.serialized_size();
86 if element_size > inner_max_size {
87 break;
88 }
89
90 max_size = Some(inner_max_size - element_size);
91 }
92
93 new_vec.push(element);
94 }
95
96 new_vec.append(vec);
97 *vec = new_vec
98 }
99 VecResizeDirection::FromEnd => {
100 for _i in 0..num_elements {
101 let constraints = max_size.map(|max_size| {
102 let mut c = Constraints::new();
103 c.max_size(max_size);
104 c.base_object_size_accounted_for = true;
105
106 c
107 });
108
109 let element = T::new_fuzzed(mutator, constraints.as_ref());
110 if let Some(inner_max_size) = max_size {
111 let element_size = element.serialized_size();
114 if element_size > inner_max_size {
115 break;
116 }
117
118 max_size = Some(inner_max_size - element_size);
119 }
120
121 vec.push(element);
122 }
123 }
124 }
125}
126
127fn shrink_vec<T, R: Rng>(vec: &mut Vec<T>, mutator: &mut Mutator<R>) {
131 if vec.is_empty() {
132 return;
133 }
134
135 let resize_count = VecResizeCount::new_fuzzed(mutator, None);
136 let mut num_elements = match resize_count {
137 VecResizeCount::Quarter => vec.len() / 4,
138 VecResizeCount::Half => vec.len() / 2,
139 VecResizeCount::ThreeQuarters => vec.len() - (vec.len() / 4),
140 VecResizeCount::FixedBytes => mutator.gen_range(1, 9),
141 VecResizeCount::AllBytes => vec.len(),
142 };
143
144 if num_elements == 0 {
145 num_elements = mutator.gen_range(0, vec.len() + 1);
146 }
147
148 num_elements = std::cmp::min(num_elements, vec.len());
149
150 if num_elements == vec.len() {
152 vec.drain(..);
153 return;
154 }
155
156 match VecResizeDirection::new_fuzzed(mutator, None) {
157 VecResizeDirection::FromBeginning => {
158 vec.drain(0..num_elements);
159 }
160 VecResizeDirection::FromEnd => {
161 vec.drain(vec.len() - num_elements..);
162 }
163 }
164}
165
166impl<T> Mutatable for Vec<T>
167where
168 T: Mutatable + SerializedSize,
169 T::RangeType: Clone,
170{
171 default type RangeType = usize;
172
173 default fn mutate<R: rand::Rng>(
174 &mut self,
175 mutator: &mut Mutator<R>,
176 constraints: Option<&Constraints<Self::RangeType>>,
177 ) {
178 const CHANCE_TO_RESIZE_VEC: f64 = 0.01;
179
180 if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
182 shrink_vec(self, mutator);
183 } else {
184 let constraints = constraints.and_then(|c| {
186 if c.max_size.is_none() {
187 None
188 } else {
189 let mut new_constraints = Constraints::new();
190 new_constraints.base_object_size_accounted_for =
191 c.base_object_size_accounted_for;
192 new_constraints.max_size = c.max_size;
193
194 Some(new_constraints)
195 }
196 });
197
198 self.as_mut_slice().mutate(mutator, constraints.as_ref());
199 }
200 }
201}
202
203impl<T> Mutatable for Vec<T>
204where
205 T: Mutatable + NewFuzzed + SerializedSize + Clone,
206 <T as Mutatable>::RangeType: Clone,
207{
208 fn mutate<R: rand::Rng>(
209 &mut self,
210 mutator: &mut Mutator<R>,
211 constraints: Option<&Constraints<Self::RangeType>>,
212 ) {
213 const CHANCE_TO_RESIZE_VEC: f64 = 0.01;
214
215 if T::max_default_object_size() == 0 {
216 return;
217 }
218
219 let can_grow = constraints
222 .map(|c| {
223 c.max_size
224 .map(|s| s > 0 && s > T::max_default_object_size())
225 .unwrap_or(true)
226 })
227 .unwrap_or(false);
228
229 if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
230 let resize_type = VecResizeType::new_fuzzed(mutator, None);
231 if resize_type == VecResizeType::Grow && can_grow {
232 grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
233 } else {
234 shrink_vec(self, mutator);
235 }
236 } else {
237 let constraints = constraints.and_then(|c| {
239 if c.max_size.is_none() {
240 None
241 } else {
242 let mut new_constraints = Constraints::new();
243 new_constraints.base_object_size_accounted_for =
244 c.base_object_size_accounted_for;
245 new_constraints.max_size = c.max_size;
246
247 Some(new_constraints)
248 }
249 });
250
251 self.as_mut_slice().mutate(mutator, constraints.as_ref());
252 }
253 }
254}
255
256impl<T> Mutatable for Vec<T>
257where
258 T: Mutatable + NewFuzzed + SerializedSize,
259 <T as Mutatable>::RangeType: Clone,
260{
261 type RangeType = usize;
262
263 default fn mutate<R: rand::Rng>(
264 &mut self,
265 mutator: &mut Mutator<R>,
266 constraints: Option<&Constraints<Self::RangeType>>,
267 ) {
268 const CHANCE_TO_RESIZE_VEC: f64 = 0.01;
269
270 if T::max_default_object_size() == 0 {
271 return;
272 }
273
274 let can_grow = constraints
277 .map(|c| c.max_size.map(|s| s > 0).unwrap_or(true))
278 .unwrap_or(false);
279
280 if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
281 let resize_type = VecResizeType::new_fuzzed(mutator, None);
282 if resize_type == VecResizeType::Grow && can_grow {
283 grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
284 } else {
285 shrink_vec(self, mutator);
286 }
287 } else {
288 let constraints = constraints.and_then(|c| {
290 if c.max_size.is_none() {
291 None
292 } else {
293 let mut new_constraints = Constraints::new();
294 new_constraints.base_object_size_accounted_for =
295 c.base_object_size_accounted_for;
296 new_constraints.max_size = c.max_size;
297
298 Some(new_constraints)
299 }
300 });
301
302 self.as_mut_slice().mutate(mutator, constraints.as_ref());
303 }
304 }
305}
306
307impl<T> Mutatable for [T]
308where
309 T: Mutatable + SerializedSize,
310 T::RangeType: Clone,
311{
312 type RangeType = T::RangeType;
313
314 default fn mutate<R: Rng>(
315 &mut self,
316 mutator: &mut Mutator<R>,
317 constraints: Option<&Constraints<Self::RangeType>>,
318 ) {
319 let mut constraints = constraints.and_then(|c| {
320 if c.max_size.is_none() {
321 None
322 } else {
323 let mut new_constraints = Constraints::new();
324 new_constraints.base_object_size_accounted_for = c.base_object_size_accounted_for;
325 new_constraints.max_size = c.max_size;
326
327 Some(new_constraints)
328 }
329 });
330
331 if let Some(max_size) = constraints.as_ref().map(|c| c.max_size).flatten().clone() {
333 if T::min_nonzero_elements_size() < max_size || T::max_default_object_size() > max_size
334 {
335 return;
336 }
337 }
338
339 for item in self.iter_mut() {
340 T::mutate(item, mutator, constraints.as_ref());
341
342 if mutator.should_early_bail_mutation() {
343 return;
344 }
345 }
346 }
347}
348
349impl<T> Mutatable for [T]
350where
351 T: Mutatable + SerializedSize + Clone,
352 T::RangeType: Clone,
353{
354 fn mutate<R: Rng>(
355 &mut self,
356 mutator: &mut Mutator<R>,
357 constraints: Option<&Constraints<Self::RangeType>>,
358 ) {
359 let mut constraints = constraints.and_then(|c| {
360 if c.max_size.is_none() {
361 None
362 } else {
363 let mut new_constraints = Constraints::new();
364 new_constraints.base_object_size_accounted_for = c.base_object_size_accounted_for;
365 new_constraints.max_size = c.max_size;
366
367 Some(new_constraints)
368 }
369 });
370
371 if let Some(max_size) = constraints.as_ref().map(|c| c.max_size).flatten().clone() {
373 if T::min_nonzero_elements_size() < max_size {
374 return;
375 }
376 }
377
378 for item in self.iter_mut() {
379 let parent_constraints = constraints.clone();
380 if let Some(constraints) = constraints.as_mut() {
381 if let Some(max_size) = constraints.max_size.as_mut() {
382 let prev_size = item.serialized_size();
383
384 if T::max_default_object_size() > *max_size {
385 let prev_obj = item.clone();
386
387 T::mutate(item, mutator, parent_constraints.as_ref());
388 if item.serialized_size() > *max_size {
389 *item = prev_obj
391 } else {
392 continue;
393 }
394 } else {
395 T::mutate(item, mutator, parent_constraints.as_ref());
396 }
397
398 let new_size = item.serialized_size();
399
400 let delta = (new_size as isize) - (prev_size as isize);
401 *max_size = (*max_size as isize - delta) as usize;
402 }
403 } else {
404 T::mutate(item, mutator, constraints.as_ref());
405 }
406
407 if mutator.should_early_bail_mutation() {
408 return;
409 }
410 }
411 }
412}
413
414impl Mutatable for bool {
415 type RangeType = u8;
416
417 fn mutate<R: Rng>(
418 &mut self,
419 mutator: &mut Mutator<R>,
420 _constraints: Option<&Constraints<Self::RangeType>>,
421 ) {
422 *self = mutator.gen_range(0u8, 2u8) != 0;
423 }
424}
425
426impl<T, I> Mutatable for UnsafeEnum<T, I>
427where
428 T: ToPrimitive<Output = I>,
429 I: BitXor<Output = I>
430 + NumCast
431 + Bounded
432 + Copy
433 + std::fmt::Debug
434 + Default
435 + DangerousNumber<I>
436 + std::fmt::Display
437 + WrappingAdd
438 + WrappingSub,
439{
440 type RangeType = I;
441
442 fn mutate<R: Rng>(
443 &mut self,
444 mutator: &mut Mutator<R>,
445 _constraints: Option<&Constraints<Self::RangeType>>,
446 ) {
447 if let UnsafeEnum::Valid(ref value) = *self {
448 *self = UnsafeEnum::Invalid(value.to_primitive());
449 }
450
451 match *self {
452 UnsafeEnum::Invalid(ref mut value) => {
453 mutator.mutate(value);
454 }
455 _ => unreachable!(),
456 }
457 }
458}
459
460impl Mutatable for AsciiString {
461 type RangeType = u8;
462
463 fn mutate<R: Rng>(
464 &mut self,
465 mutator: &mut Mutator<R>,
466 _constraints: Option<&Constraints<Self::RangeType>>,
467 ) {
468 trace!("performing mutation on an AsciiString");
469
470 let num_mutations = mutator.gen_range(1, self.inner.len());
472 for idx in index::sample(&mut mutator.rng, self.inner.len(), num_mutations).iter() {
473 self.inner[idx] = AsciiChar::new_fuzzed(mutator, None);
474 }
475 }
476}
477
478impl Mutatable for Utf8String {
479 type RangeType = u8;
480
481 fn mutate<R: Rng>(
482 &mut self,
483 mutator: &mut Mutator<R>,
484 _constraints: Option<&Constraints<Self::RangeType>>,
485 ) {
486 trace!("performing mutation on a Utf8String");
487
488 let num_mutations = mutator.gen_range(1, self.inner.len());
490 for idx in index::sample(&mut mutator.rng, self.inner.len(), num_mutations).iter() {
491 self.inner[idx] = Utf8Char::new_fuzzed(mutator, None);
492 }
493 }
494}
495
496macro_rules! impl_mutatable {
497 ( $($name:ident),* ) => {
498 $(
499 impl Mutatable for $name {
500 type RangeType = $name;
501
502 #[inline(always)]
503 fn mutate<R: Rng>(&mut self, mutator: &mut Mutator<R>, _constraints: Option<&Constraints<Self::RangeType>>) {
504 mutator.mutate(self);
505 }
506 }
507 )*
508 }
509}
510
511impl_mutatable!(u64, u32, u16, u8);
512
513impl Mutatable for i8 {
514 type RangeType = i8;
515
516 #[inline(always)]
517 fn mutate<R: Rng>(
518 &mut self,
519 mutator: &mut Mutator<R>,
520 _constraints: Option<&Constraints<Self::RangeType>>,
521 ) {
522 let mut val = *self as u8;
523 mutator.mutate(&mut val);
524 *self = val as i8;
525 }
526}
527
528impl Mutatable for i16 {
529 type RangeType = i16;
530
531 #[inline(always)]
532 fn mutate<R: Rng>(
533 &mut self,
534 mutator: &mut Mutator<R>,
535 _constraints: Option<&Constraints<Self::RangeType>>,
536 ) {
537 let mut val = *self as u16;
538 mutator.mutate(&mut val);
539 *self = val as i16;
540 }
541}
542
543impl Mutatable for i32 {
544 type RangeType = i32;
545
546 #[inline(always)]
547 fn mutate<R: Rng>(
548 &mut self,
549 mutator: &mut Mutator<R>,
550 _constraints: Option<&Constraints<Self::RangeType>>,
551 ) {
552 let mut val = *self as u32;
553 mutator.mutate(&mut val);
554 *self = val as i32;
555 }
556}
557
558impl Mutatable for i64 {
559 type RangeType = i64;
560
561 #[inline(always)]
562 fn mutate<R: Rng>(
563 &mut self,
564 mutator: &mut Mutator<R>,
565 _constraints: Option<&Constraints<Self::RangeType>>,
566 ) {
567 let mut val = *self as u64;
568 mutator.mutate(&mut val);
569 *self = val as i64;
570 }
571}
572
573impl<T> Mutatable for [T; 0]
574where
575 T: Mutatable,
576{
577 type RangeType = u8;
578
579 fn mutate<R: Rng>(
580 &mut self,
581 _mutator: &mut Mutator<R>,
582 _constraints: Option<&Constraints<Self::RangeType>>,
583 ) {
584 }
586}
587
588impl Mutatable for *const std::ffi::c_void {
589 type RangeType = u8;
590
591 fn mutate<R: Rng>(
592 &mut self,
593 _mutator: &mut Mutator<R>,
594 _constraints: Option<&Constraints<Self::RangeType>>,
595 ) {
596 }
598}
599
600impl Mutatable for *mut std::ffi::c_void {
601 type RangeType = u8;
602
603 fn mutate<R: Rng>(
604 &mut self,
605 _mutator: &mut Mutator<R>,
606 _constraints: Option<&Constraints<Self::RangeType>>,
607 ) {
608 }
610}
611
612impl<T> Mutatable for Option<T>
613where
614 T: Mutatable + NewFuzzed<RangeType = <T as Mutatable>::RangeType>,
615{
616 type RangeType = <T as Mutatable>::RangeType;
617
618 fn mutate<R: Rng>(
619 &mut self,
620 mutator: &mut Mutator<R>,
621 constraints: Option<&Constraints<Self::RangeType>>,
622 ) {
623 const CHANCE_TO_FLIP_OPTION_STATE: f64 = 0.01;
624 match self {
625 Some(inner) => {
626 if mutator.gen_chance(CHANCE_TO_FLIP_OPTION_STATE) {
628 *self = None;
629 } else {
630 inner.mutate(mutator, constraints);
631 }
632 }
633 None => {
634 if mutator.gen_chance(CHANCE_TO_FLIP_OPTION_STATE) {
635 let mut new_item = T::new_fuzzed(mutator, constraints);
636
637 *self = Some(new_item);
638 }
639 }
640 }
641 }
642}
643
644impl<T> Mutatable for Box<T>
645where
646 T: Mutatable + NewFuzzed<RangeType = <T as Mutatable>::RangeType>,
647{
648 type RangeType = <T as Mutatable>::RangeType;
649
650 fn mutate<R: Rng>(
651 &mut self,
652 mutator: &mut Mutator<R>,
653 constraints: Option<&Constraints<Self::RangeType>>,
654 ) {
655 self.as_mut().mutate(mutator, constraints);
656 }
657}
658
659macro_rules! impl_mutatable_array {
660 ( $($size:expr),* ) => {
661 $(
662 impl<T> Mutatable for [T; $size]
663 where
664 T: Mutatable + SerializedSize,
665 T::RangeType: Clone,
666 {
667 type RangeType = T::RangeType;
668
669 #[inline(always)]
670 fn mutate<R: Rng>(&mut self, mutator: &mut Mutator<R>, constraints: Option<&Constraints<Self::RangeType>>) {
671 self[..].mutate(mutator, constraints);
673 }
674 }
675 )*
676 }
677}
678
679impl_mutatable_array!(
680 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
681 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
682 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
683);