@@ -38,17 +38,23 @@ enum VecResizeType {
38
38
fn grow_vec < T : NewFuzzed + SerializedSize , R : Rng > (
39
39
vec : & mut Vec < T > ,
40
40
mutator : & mut Mutator < R > ,
41
+ max_elems : Option < usize > ,
41
42
mut max_size : Option < usize > ,
42
43
) {
43
44
let resize_count = VecResizeCount :: new_fuzzed ( mutator, None ) ;
45
+ let resize_max = if let Some ( max) = max_elems {
46
+ max
47
+ } else {
48
+ 9 // old magic value from lain
49
+ } ;
44
50
let mut num_elements = if vec. is_empty ( ) {
45
- mutator. gen_range ( 1 , 9 )
51
+ mutator. gen_range ( 1 , resize_max )
46
52
} else {
47
53
match resize_count {
48
54
VecResizeCount :: Quarter => vec. len ( ) / 4 ,
49
55
VecResizeCount :: Half => vec. len ( ) / 2 ,
50
56
VecResizeCount :: ThreeQuarters => vec. len ( ) - ( vec. len ( ) / 4 ) ,
51
- VecResizeCount :: FixedBytes => mutator. gen_range ( 1 , 9 ) ,
57
+ VecResizeCount :: FixedBytes => mutator. gen_range ( 1 , resize_max ) ,
52
58
VecResizeCount :: AllBytes => mutator. gen_range ( 1 , vec. len ( ) + 1 ) ,
53
59
}
54
60
} ;
@@ -58,6 +64,10 @@ fn grow_vec<T: NewFuzzed + SerializedSize, R: Rng>(
58
64
num_elements = min ( num_elements, max_size / T :: max_default_object_size ( ) ) ;
59
65
}
60
66
67
+ if let Some ( max_elems) = max_elems {
68
+ num_elements = min ( max_elems - vec. len ( ) , num_elements) ;
69
+ }
70
+
61
71
if num_elements == 0 {
62
72
return ;
63
73
}
@@ -125,28 +135,30 @@ fn grow_vec<T: NewFuzzed + SerializedSize, R: Rng>(
125
135
/// Shrinks a `Vec`.
126
136
/// This will randomly select to resize by a factor of 1/4, 1/2, 3/4, or a fixed number of bytes
127
137
/// in the range of [1, 8]. Elements may be removed randomly from the beginning or end of the the vec
128
- fn shrink_vec < T , R : Rng > ( vec : & mut Vec < T > , mutator : & mut Mutator < R > ) {
138
+ fn shrink_vec < T , R : Rng > ( vec : & mut Vec < T > , mutator : & mut Mutator < R > , min_size : Option < usize > ) {
129
139
if vec. is_empty ( ) {
130
140
return ;
131
141
}
132
142
143
+ let min_size = if let Some ( min) = min_size { min } else { 0 } ;
144
+
133
145
let resize_count = VecResizeCount :: new_fuzzed ( mutator, None ) ;
134
146
let mut num_elements = match resize_count {
135
147
VecResizeCount :: Quarter => vec. len ( ) / 4 ,
136
148
VecResizeCount :: Half => vec. len ( ) / 2 ,
137
149
VecResizeCount :: ThreeQuarters => vec. len ( ) - ( vec. len ( ) / 4 ) ,
138
- VecResizeCount :: FixedBytes => mutator. gen_range ( 1 , 9 ) ,
139
- VecResizeCount :: AllBytes => vec. len ( ) ,
150
+ VecResizeCount :: FixedBytes => min ( min ( mutator. gen_range ( 1 , 9 ) , vec . len ( ) ) , min_size ) ,
151
+ VecResizeCount :: AllBytes => min ( vec. len ( ) , min_size ) ,
140
152
} ;
141
153
142
154
if num_elements == 0 {
143
155
num_elements = mutator. gen_range ( 0 , vec. len ( ) + 1 ) ;
144
156
}
145
157
146
- num_elements = std:: cmp:: min ( num_elements, vec. len ( ) ) ;
158
+ num_elements = std:: cmp:: min ( num_elements, vec. len ( ) - min_size ) ;
147
159
148
160
// Special case probably isn't required here, but better to be explicit
149
- if num_elements == vec. len ( ) {
161
+ if num_elements == vec. len ( ) && min_size == 0 {
150
162
vec. drain ( ..) ;
151
163
return ;
152
164
}
@@ -177,7 +189,7 @@ where
177
189
178
190
// 1% chance to resize this vec
179
191
if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
180
- shrink_vec ( self , mutator) ;
192
+ shrink_vec ( self , mutator, Some ( 1 ) ) ;
181
193
} else {
182
194
// Recreate the constraints so that the min/max types match
183
195
let constraints = constraints. and_then ( |c| {
@@ -209,44 +221,82 @@ where
209
221
constraints : Option < & Constraints < Self :: RangeType > > ,
210
222
) {
211
223
const CHANCE_TO_RESIZE_VEC : f64 = 0.01 ;
224
+ const CHANCE_TO_RESIZE_EMPTY_VEC : f64 = 0.33 ;
212
225
213
226
if T :: max_default_object_size ( ) == 0 {
214
227
return ;
215
228
}
216
229
217
230
// we can grow the vector if we have no size constraint or the max size quota hasn't
218
231
// been fulfilled
219
- let can_grow = constraints
220
- . map ( |c| {
221
- c. max_size
222
- . map ( |s| s > 0 && s > T :: max_default_object_size ( ) )
223
- . unwrap_or ( true )
224
- } )
225
- . unwrap_or ( false ) ;
232
+ let mut can_grow = true ;
233
+ if let Some ( max_elems) = constraints. and_then ( |c| c. max ) {
234
+ if self . len ( ) >= max_elems {
235
+ can_grow = false ;
236
+ }
237
+ }
226
238
227
- if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
228
- let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
229
- if resize_type == VecResizeType :: Grow && can_grow {
230
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
239
+ if let Some ( max_size) = constraints. and_then ( |c| c. max_size ) {
240
+ if self . len ( ) >= max_size / T :: max_default_object_size ( ) {
241
+ can_grow = false ;
242
+ }
243
+ }
244
+
245
+ if self . is_empty ( ) {
246
+ if mutator. gen_chance ( CHANCE_TO_RESIZE_EMPTY_VEC ) {
247
+ grow_vec (
248
+ self ,
249
+ mutator,
250
+ constraints. and_then ( |c| c. max ) ,
251
+ constraints. and_then ( |c| c. max_size ) ,
252
+ ) ;
231
253
} else {
232
- shrink_vec ( self , mutator) ;
254
+ // Recreate the constraints so that the min/max types match
255
+ let constraints = constraints. and_then ( |c| {
256
+ if c. max_size . is_none ( ) {
257
+ None
258
+ } else {
259
+ let mut new_constraints = Constraints :: new ( ) ;
260
+ new_constraints. base_object_size_accounted_for =
261
+ c. base_object_size_accounted_for ;
262
+ new_constraints. max_size = c. max_size ;
263
+
264
+ Some ( new_constraints)
265
+ }
266
+ } ) ;
267
+
268
+ self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
233
269
}
234
270
} else {
235
- // Recreate the constraints so that the min/max types match
236
- let constraints = constraints. and_then ( |c| {
237
- if c. max_size . is_none ( ) {
238
- None
271
+ if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
272
+ let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
273
+ if resize_type == VecResizeType :: Grow && can_grow {
274
+ grow_vec (
275
+ self ,
276
+ mutator,
277
+ constraints. and_then ( |c| c. max ) ,
278
+ constraints. and_then ( |c| c. max_size ) ,
279
+ ) ;
239
280
} else {
240
- let mut new_constraints = Constraints :: new ( ) ;
241
- new_constraints. base_object_size_accounted_for =
242
- c. base_object_size_accounted_for ;
243
- new_constraints. max_size = c. max_size ;
244
-
245
- Some ( new_constraints)
281
+ shrink_vec ( self , mutator, constraints. and_then ( |c| c. min ) ) ;
246
282
}
247
- } ) ;
283
+ } else {
284
+ // Recreate the constraints so that the min/max types match
285
+ let constraints = constraints. and_then ( |c| {
286
+ if c. max_size . is_none ( ) {
287
+ None
288
+ } else {
289
+ let mut new_constraints = Constraints :: new ( ) ;
290
+ new_constraints. base_object_size_accounted_for =
291
+ c. base_object_size_accounted_for ;
292
+ new_constraints. max_size = c. max_size ;
248
293
249
- self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
294
+ Some ( new_constraints)
295
+ }
296
+ } ) ;
297
+
298
+ self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
299
+ }
250
300
}
251
301
}
252
302
}
@@ -264,6 +314,7 @@ where
264
314
constraints : Option < & Constraints < Self :: RangeType > > ,
265
315
) {
266
316
const CHANCE_TO_RESIZE_VEC : f64 = 0.01 ;
317
+ const CHANCE_TO_RESIZE_EMPTY_VEC : f64 = 0.33 ;
267
318
268
319
if T :: max_default_object_size ( ) == 0 {
269
320
return ;
@@ -275,29 +326,61 @@ where
275
326
. map ( |c| c. max_size . map ( |s| s > 0 ) . unwrap_or ( true ) )
276
327
. unwrap_or ( false ) ;
277
328
278
- if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
279
- let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
280
- if resize_type == VecResizeType :: Grow && can_grow {
281
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
329
+ if self . is_empty ( ) {
330
+ if mutator. gen_chance ( CHANCE_TO_RESIZE_EMPTY_VEC ) {
331
+ grow_vec (
332
+ self ,
333
+ mutator,
334
+ constraints. and_then ( |c| c. max ) ,
335
+ constraints. and_then ( |c| c. max_size ) ,
336
+ ) ;
282
337
} else {
283
- shrink_vec ( self , mutator) ;
338
+ // Recreate the constraints so that the min/max types match
339
+ let constraints = constraints. and_then ( |c| {
340
+ if c. max_size . is_none ( ) {
341
+ None
342
+ } else {
343
+ let mut new_constraints = Constraints :: new ( ) ;
344
+ new_constraints. base_object_size_accounted_for =
345
+ c. base_object_size_accounted_for ;
346
+ new_constraints. max_size = c. max_size ;
347
+
348
+ Some ( new_constraints)
349
+ }
350
+ } ) ;
351
+
352
+ self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
284
353
}
285
354
} else {
286
- // Recreate the constraints so that the min/max types match
287
- let constraints = constraints. and_then ( |c| {
288
- if c. max_size . is_none ( ) {
289
- None
355
+ if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
356
+ let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
357
+ if resize_type == VecResizeType :: Grow && can_grow {
358
+ grow_vec (
359
+ self ,
360
+ mutator,
361
+ constraints. and_then ( |c| c. max ) ,
362
+ constraints. and_then ( |c| c. max_size ) ,
363
+ ) ;
290
364
} else {
291
- let mut new_constraints = Constraints :: new ( ) ;
292
- new_constraints. base_object_size_accounted_for =
293
- c. base_object_size_accounted_for ;
294
- new_constraints. max_size = c. max_size ;
295
-
296
- Some ( new_constraints)
365
+ shrink_vec ( self , mutator, constraints. and_then ( |c| c. min ) ) ;
297
366
}
298
- } ) ;
367
+ } else {
368
+ // Recreate the constraints so that the min/max types match
369
+ let constraints = constraints. and_then ( |c| {
370
+ if c. max_size . is_none ( ) {
371
+ None
372
+ } else {
373
+ let mut new_constraints = Constraints :: new ( ) ;
374
+ new_constraints. base_object_size_accounted_for =
375
+ c. base_object_size_accounted_for ;
376
+ new_constraints. max_size = c. max_size ;
299
377
300
- self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
378
+ Some ( new_constraints)
379
+ }
380
+ } ) ;
381
+
382
+ self . as_mut_slice ( ) . mutate ( mutator, constraints. as_ref ( ) ) ;
383
+ }
301
384
}
302
385
}
303
386
}
@@ -618,18 +701,19 @@ where
618
701
mutator : & mut Mutator < R > ,
619
702
constraints : Option < & Constraints < Self :: RangeType > > ,
620
703
) {
621
- const CHANCE_TO_FLIP_OPTION_STATE : f64 = 0.01 ;
704
+ const CHANCE_TO_FLIP_SOME_STATE : f64 = 0.05 ;
705
+ const CHANCE_TO_FLIP_NONE_STATE : f64 = 0.10 ;
622
706
match self {
623
707
Some ( inner) => {
624
708
// small chance to make this None
625
- if mutator. gen_chance ( CHANCE_TO_FLIP_OPTION_STATE ) {
709
+ if mutator. gen_chance ( CHANCE_TO_FLIP_SOME_STATE ) {
626
710
* self = None ;
627
711
} else {
628
712
inner. mutate ( mutator, constraints) ;
629
713
}
630
714
}
631
715
None => {
632
- if mutator. gen_chance ( CHANCE_TO_FLIP_OPTION_STATE ) {
716
+ if mutator. gen_chance ( CHANCE_TO_FLIP_NONE_STATE ) {
633
717
let new_item = T :: new_fuzzed ( mutator, constraints) ;
634
718
635
719
* self = Some ( new_item) ;
0 commit comments