@@ -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| {
@@ -217,25 +229,56 @@ where
217
229
218
230
// we can grow the vector if we have no size constraint or the max size quota hasn't
219
231
// been fulfilled
220
- let can_grow = constraints
221
- . map ( |c| {
222
- c. max_size
223
- . map ( |s| s > 0 && s > T :: max_default_object_size ( ) )
224
- . unwrap_or ( true )
225
- } )
226
- . 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
+ }
238
+
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
+ }
227
244
228
245
if self . is_empty ( ) {
229
246
if mutator. gen_chance ( CHANCE_TO_RESIZE_EMPTY_VEC ) {
230
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
247
+ grow_vec (
248
+ self ,
249
+ mutator,
250
+ constraints. and_then ( |c| c. max ) ,
251
+ constraints. and_then ( |c| c. max_size ) ,
252
+ ) ;
253
+ } else {
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 ( ) ) ;
231
269
}
232
270
} else {
233
271
if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
234
272
let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
235
273
if resize_type == VecResizeType :: Grow && can_grow {
236
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
274
+ grow_vec (
275
+ self ,
276
+ mutator,
277
+ constraints. and_then ( |c| c. max ) ,
278
+ constraints. and_then ( |c| c. max_size ) ,
279
+ ) ;
237
280
} else {
238
- shrink_vec ( self , mutator) ;
281
+ shrink_vec ( self , mutator, constraints . and_then ( |c| c . min ) ) ;
239
282
}
240
283
} else {
241
284
// Recreate the constraints so that the min/max types match
@@ -285,15 +328,41 @@ where
285
328
286
329
if self . is_empty ( ) {
287
330
if mutator. gen_chance ( CHANCE_TO_RESIZE_EMPTY_VEC ) {
288
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
331
+ grow_vec (
332
+ self ,
333
+ mutator,
334
+ constraints. and_then ( |c| c. max ) ,
335
+ constraints. and_then ( |c| c. max_size ) ,
336
+ ) ;
337
+ } else {
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 ( ) ) ;
289
353
}
290
354
} else {
291
355
if mutator. gen_chance ( CHANCE_TO_RESIZE_VEC ) {
292
356
let resize_type = VecResizeType :: new_fuzzed ( mutator, None ) ;
293
357
if resize_type == VecResizeType :: Grow && can_grow {
294
- grow_vec ( self , mutator, constraints. and_then ( |c| c. max_size ) ) ;
358
+ grow_vec (
359
+ self ,
360
+ mutator,
361
+ constraints. and_then ( |c| c. max ) ,
362
+ constraints. and_then ( |c| c. max_size ) ,
363
+ ) ;
295
364
} else {
296
- shrink_vec ( self , mutator) ;
365
+ shrink_vec ( self , mutator, constraints . and_then ( |c| c . min ) ) ;
297
366
}
298
367
} else {
299
368
// Recreate the constraints so that the min/max types match
0 commit comments