@@ -157,39 +157,31 @@ impl AbiMutator for I256 {
157
157
158
158
impl AbiMutator for Address {
159
159
#[ instrument( name = "Address::flip_random_bit" , skip( _size, test_runner) , ret) ]
160
- fn flip_random_bit ( mut self , _size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
161
- flip_random_bit_in_slice ( self . as_mut_slice ( ) , test_runner) ?;
162
- Some ( self )
160
+ fn flip_random_bit ( self , _size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
161
+ let mut mutated = self ;
162
+ flip_random_bit_in_slice ( mutated. as_mut_slice ( ) , test_runner) ?;
163
+ ( self != mutated) . then_some ( mutated)
163
164
}
164
165
165
166
#[ instrument( name = "Address::mutate_interesting_byte" , skip( _size, test_runner) , ret) ]
166
- fn mutate_interesting_byte (
167
- mut self ,
168
- _size : usize ,
169
- test_runner : & mut TestRunner ,
170
- ) -> Option < Self > {
171
- mutate_interesting_byte_slice ( self . as_mut_slice ( ) , test_runner) ?;
172
- Some ( self )
167
+ fn mutate_interesting_byte ( self , _size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
168
+ let mut mutated = self ;
169
+ mutate_interesting_byte_slice ( mutated. as_mut_slice ( ) , test_runner) ?;
170
+ ( self != mutated) . then_some ( mutated)
173
171
}
174
172
175
173
#[ instrument( name = "Address::mutate_interesting_word" , skip( _size, test_runner) , ret) ]
176
- fn mutate_interesting_word (
177
- mut self ,
178
- _size : usize ,
179
- test_runner : & mut TestRunner ,
180
- ) -> Option < Self > {
181
- mutate_interesting_word_slice ( self . as_mut_slice ( ) , test_runner) ?;
182
- Some ( self )
174
+ fn mutate_interesting_word ( self , _size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
175
+ let mut mutated = self ;
176
+ mutate_interesting_word_slice ( mutated. as_mut_slice ( ) , test_runner) ?;
177
+ ( self != mutated) . then_some ( mutated)
183
178
}
184
179
185
180
#[ instrument( name = "Address::mutate_interesting_dword" , skip( _size, test_runner) , ret) ]
186
- fn mutate_interesting_dword (
187
- mut self ,
188
- _size : usize ,
189
- test_runner : & mut TestRunner ,
190
- ) -> Option < Self > {
191
- mutate_interesting_dword_slice ( self . as_mut_slice ( ) , test_runner) ?;
192
- Some ( self )
181
+ fn mutate_interesting_dword ( self , _size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
182
+ let mut mutated = self ;
183
+ mutate_interesting_dword_slice ( mutated. as_mut_slice ( ) , test_runner) ?;
184
+ ( self != mutated) . then_some ( mutated)
193
185
}
194
186
}
195
187
@@ -199,31 +191,31 @@ impl AbiMutator for Word {
199
191
let mut bytes = self ;
200
192
let slice = & mut bytes[ ..size] ;
201
193
flip_random_bit_in_slice ( slice, test_runner) ?;
202
- Some ( bytes)
194
+ ( self != bytes ) . then_some ( bytes)
203
195
}
204
196
205
197
#[ instrument( name = "Word::mutate_interesting_byte" , skip( size, test_runner) , ret) ]
206
198
fn mutate_interesting_byte ( self , size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
207
199
let mut bytes = self ;
208
200
let slice = & mut bytes[ ..size] ;
209
201
mutate_interesting_byte_slice ( slice, test_runner) ?;
210
- Some ( bytes)
202
+ ( self != bytes ) . then_some ( bytes)
211
203
}
212
204
213
205
#[ instrument( name = "Word::mutate_interesting_word" , skip( size, test_runner) , ret) ]
214
206
fn mutate_interesting_word ( self , size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
215
207
let mut bytes = self ;
216
208
let slice = & mut bytes[ ..size] ;
217
209
mutate_interesting_word_slice ( slice, test_runner) ?;
218
- Some ( bytes)
210
+ ( self != bytes ) . then_some ( bytes)
219
211
}
220
212
221
213
#[ instrument( name = "Word::mutate_interesting_dword" , skip( size, test_runner) , ret) ]
222
214
fn mutate_interesting_dword ( self , size : usize , test_runner : & mut TestRunner ) -> Option < Self > {
223
215
let mut bytes = self ;
224
216
let slice = & mut bytes[ ..size] ;
225
217
mutate_interesting_dword_slice ( slice, test_runner) ?;
226
- Some ( bytes)
218
+ ( self != bytes ) . then_some ( bytes)
227
219
}
228
220
}
229
221
@@ -306,228 +298,105 @@ mod tests {
306
298
use proptest:: test_runner:: Config ;
307
299
308
300
#[ test]
309
- fn test_increment_decrement_u256 ( ) {
301
+ fn test_mutate_uint ( ) {
310
302
let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
303
+ let size = 32 ;
311
304
312
- let mut increment_decrement = |value : U256 , expected : Vec < U256 > | {
313
- for _ in 0 ..100 {
314
- let mutated = value. increment_decrement ( 8 , & mut runner) ;
315
- assert ! (
316
- mutated. is_none( ) || mutated. is_some_and( |mutated| expected. contains( & mutated) )
317
- ) ;
318
- }
319
- } ;
320
-
321
- increment_decrement ( U256 :: ZERO , vec ! [ U256 :: ONE ] ) ;
322
- increment_decrement ( U256 :: from ( 255 ) , vec ! [ U256 :: from( 254 ) ] ) ;
323
- increment_decrement ( U256 :: from ( 64 ) , vec ! [ U256 :: from( 63 ) , U256 :: from( 65 ) ] ) ;
324
- }
325
-
326
- #[ test]
327
- fn test_increment_decrement_i256 ( ) {
328
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
329
-
330
- let mut increment_decrement = |value : I256 , expected : Vec < I256 > | {
331
- for _ in 0 ..100 {
332
- let mutated = value. increment_decrement ( 8 , & mut runner) ;
333
- assert ! (
334
- mutated. is_none( ) || mutated. is_some_and( |mutated| expected. contains( & mutated) )
335
- ) ;
336
- }
337
- } ;
338
-
339
- increment_decrement (
340
- I256 :: from_dec_str ( "-128" ) . unwrap ( ) ,
341
- vec ! [ I256 :: from_dec_str( "-127" ) . unwrap( ) ] ,
342
- ) ;
343
- increment_decrement (
344
- I256 :: from_dec_str ( "127" ) . unwrap ( ) ,
345
- vec ! [ I256 :: from_dec_str( "126" ) . unwrap( ) ] ,
346
- ) ;
347
- increment_decrement (
348
- I256 :: from_dec_str ( "-47" ) . unwrap ( ) ,
349
- vec ! [ I256 :: from_dec_str( "-48" ) . unwrap( ) , I256 :: from_dec_str( "-46" ) . unwrap( ) ] ,
350
- ) ;
351
- increment_decrement (
352
- I256 :: from_dec_str ( "47" ) . unwrap ( ) ,
353
- vec ! [ I256 :: from_dec_str( "48" ) . unwrap( ) , I256 :: from_dec_str( "46" ) . unwrap( ) ] ,
354
- ) ;
355
- }
356
-
357
- #[ test]
358
- fn test_bit_flip_u256 ( ) {
359
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
360
- let size = 8 ;
361
-
362
- let mut test_bit_flip = |value : U256 | {
363
- for _ in 0 ..100 {
364
- let flipped = U256 :: flip_random_bit ( value, size, & mut runner) ;
365
- assert ! (
366
- flipped. is_none( )
367
- || flipped. is_some_and(
368
- |flipped| flipped != value && flipped < ( U256 :: from( 1 ) << size)
369
- )
370
- ) ;
371
- }
372
- } ;
373
-
374
- test_bit_flip ( U256 :: ZERO ) ;
375
- test_bit_flip ( U256 :: ONE ) ;
376
- test_bit_flip ( U256 :: MAX ) ;
377
- test_bit_flip ( U256 :: from ( 255 ) ) ;
378
- }
379
-
380
- #[ test]
381
- fn test_bit_flip_i256 ( ) {
382
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
383
- let size = 8 ;
384
-
385
- let mut test_bit_flip = |value : I256 | {
386
- for _ in 0 ..100 {
387
- let flipped = I256 :: flip_random_bit ( value, size, & mut runner) ;
388
- assert ! (
389
- flipped. is_none( )
390
- || flipped. is_some_and( |flipped| {
391
- flipped != value
392
- && flipped. abs( ) . unsigned_abs( ) < ( U256 :: from( 1 ) << ( size - 1 ) )
393
- } )
394
- ) ;
395
- }
396
- } ;
397
-
398
- test_bit_flip ( I256 :: from_dec_str ( "-128" ) . unwrap ( ) ) ;
399
- test_bit_flip ( I256 :: from_dec_str ( "127" ) . unwrap ( ) ) ;
400
- test_bit_flip ( I256 :: MAX ) ;
401
- test_bit_flip ( I256 :: MIN ) ;
402
- test_bit_flip ( I256 :: MINUS_ONE ) ;
403
- }
404
-
405
- #[ test]
406
- fn test_mutate_interesting_byte_u256 ( ) {
407
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
408
- let value = U256 :: from ( 0 ) ;
409
- let size = 8 ;
305
+ let test_values =
306
+ vec ! [ U256 :: ZERO , U256 :: ONE , U256 :: from( 12345u64 ) , U256 :: from( 255 ) , U256 :: MAX ] ;
410
307
411
- for _ in 0 .. 100 {
412
- let mutated = U256 :: mutate_interesting_byte ( value, size , & mut runner ) ;
308
+ # [ track_caller ]
309
+ fn validate_mutation ( value : U256 , mutated : Option < U256 > ) {
413
310
assert ! (
414
- mutated. is_none( )
415
- || mutated. is_some_and(
416
- |mutated| mutated != value && mutated < ( U256 :: from( 1 ) << size)
417
- )
311
+ mutated. is_none( ) || mutated. is_some_and( |m| m != value) ,
312
+ "Mutation failed: value = {value:?}, mutated = {mutated:?}"
418
313
) ;
419
314
}
420
- }
421
315
422
- #[ test]
423
- fn test_mutate_interesting_word_u256 ( ) {
424
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
425
- let value = U256 :: from ( 0 ) ;
426
- let size = 16 ;
427
-
428
- for _ in 0 ..100 {
429
- let mutated = U256 :: mutate_interesting_word ( value, size, & mut runner) ;
430
- assert ! (
431
- mutated. is_none( )
432
- || mutated. is_some_and(
433
- |mutated| mutated != value && mutated < ( U256 :: from( 1 ) << size)
434
- )
435
- ) ;
316
+ for value in test_values {
317
+ for _ in 0 ..100 {
318
+ validate_mutation ( value, U256 :: increment_decrement ( value, size, & mut runner) ) ;
319
+ validate_mutation ( value, U256 :: flip_random_bit ( value, size, & mut runner) ) ;
320
+ validate_mutation ( value, U256 :: mutate_interesting_byte ( value, size, & mut runner) ) ;
321
+ validate_mutation ( value, U256 :: mutate_interesting_word ( value, size, & mut runner) ) ;
322
+ validate_mutation ( value, U256 :: mutate_interesting_dword ( value, size, & mut runner) ) ;
323
+ }
436
324
}
437
325
}
438
326
439
327
#[ test]
440
- fn test_mutate_interesting_dword_u256 ( ) {
328
+ fn test_mutate_int ( ) {
441
329
let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
442
- let value = U256 :: from ( 0 ) ;
443
330
let size = 32 ;
444
331
445
- for _ in 0 ..100 {
446
- let mutated = U256 :: mutate_interesting_dword ( value, size, & mut runner) ;
332
+ let test_values = vec ! [
333
+ I256 :: ZERO ,
334
+ I256 :: ONE ,
335
+ I256 :: MINUS_ONE ,
336
+ I256 :: from_dec_str( "12345" ) . unwrap( ) ,
337
+ I256 :: from_dec_str( "-54321" ) . unwrap( ) ,
338
+ I256 :: from_dec_str( "340282366920938463463374607431768211455" ) . unwrap( ) ,
339
+ I256 :: from_dec_str( "-340282366920938463463374607431768211455" ) . unwrap( ) ,
340
+ ] ;
341
+
342
+ #[ track_caller]
343
+ fn validate_mutation ( value : I256 , mutated : Option < I256 > ) {
447
344
assert ! (
448
- mutated. is_none( )
449
- || mutated. is_some_and(
450
- |mutated| mutated != value && mutated < ( U256 :: from( 1 ) << size)
451
- )
345
+ mutated. is_none( ) || mutated. is_some_and( |m| m != value) ,
346
+ "Mutation failed: value = {value:?}, mutated = {mutated:?}"
452
347
) ;
453
348
}
454
- }
455
349
456
- #[ test]
457
- fn test_mutate_interesting_byte_i256 ( ) {
458
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
459
- let value = I256 :: ZERO ;
460
- let size = 8 ;
461
-
462
- for _ in 0 ..100 {
463
- let mutated = I256 :: mutate_interesting_byte ( value, size, & mut runner) ;
464
- assert ! (
465
- mutated. is_none( )
466
- || mutated. is_some_and( |mutated| mutated != value
467
- && mutated. abs( ) . unsigned_abs( ) < ( U256 :: from( 1 ) << ( size - 1 ) ) )
468
- )
350
+ for value in test_values {
351
+ for _ in 0 ..100 {
352
+ validate_mutation ( value, I256 :: increment_decrement ( value, size, & mut runner) ) ;
353
+ validate_mutation ( value, I256 :: flip_random_bit ( value, size, & mut runner) ) ;
354
+ validate_mutation ( value, I256 :: mutate_interesting_byte ( value, size, & mut runner) ) ;
355
+ validate_mutation ( value, I256 :: mutate_interesting_word ( value, size, & mut runner) ) ;
356
+ validate_mutation ( value, I256 :: mutate_interesting_dword ( value, size, & mut runner) ) ;
357
+ }
469
358
}
470
359
}
471
360
472
361
#[ test]
473
- fn test_mutate_interesting_word_i256 ( ) {
362
+ fn test_mutate_address ( ) {
474
363
let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
475
- let value = I256 :: ZERO ;
476
- let size = 16 ;
364
+ let value = Address :: random ( ) ;
477
365
478
- for _ in 0 .. 100 {
479
- let mutated = I256 :: mutate_interesting_word ( value, size , & mut runner ) ;
366
+ # [ track_caller ]
367
+ fn validate_mutation ( value : Address , mutated : Option < Address > ) {
480
368
assert ! (
481
- mutated. is_none( )
482
- || mutated. is_some_and( |mutated| mutated != value
483
- && mutated. abs( ) . unsigned_abs( ) < ( U256 :: from( 1 ) << ( size - 1 ) ) )
484
- )
369
+ mutated. is_none( ) || mutated. is_some_and( |mutated| mutated != value) ,
370
+ "Mutation failed for value: {value:?}, result: {mutated:?}"
371
+ ) ;
485
372
}
486
- }
487
-
488
- #[ test]
489
- fn test_mutate_interesting_dword_i256 ( ) {
490
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
491
- let value = I256 :: ZERO ;
492
- let size = 32 ;
493
373
494
374
for _ in 0 ..100 {
495
- let mutated = I256 :: mutate_interesting_dword ( value, size, & mut runner) ;
496
- assert ! (
497
- mutated. is_none( )
498
- || mutated. is_some_and( |mutated| mutated != value
499
- && mutated. abs( ) . unsigned_abs( ) < ( U256 :: from( 1 ) << ( size - 1 ) ) )
500
- )
375
+ validate_mutation ( value, Address :: flip_random_bit ( value, 20 , & mut runner) ) ;
376
+ validate_mutation ( value, Address :: mutate_interesting_byte ( value, 20 , & mut runner) ) ;
377
+ validate_mutation ( value, Address :: mutate_interesting_word ( value, 20 , & mut runner) ) ;
378
+ validate_mutation ( value, Address :: mutate_interesting_dword ( value, 20 , & mut runner) ) ;
501
379
}
502
380
}
503
381
504
382
#[ test]
505
- fn test_mutate_address ( ) {
383
+ fn test_mutate_word ( ) {
506
384
let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
507
- for _ in 0 ..100 {
508
- let value = Address :: random ( ) ;
509
- assert_ne ! ( value, Address :: flip_random_bit( value, 20 , & mut runner) . unwrap( ) ) ;
510
- let value1 = Address :: random ( ) ;
511
- assert_ne ! ( value1, Address :: mutate_interesting_byte( value1, 20 , & mut runner) . unwrap( ) ) ;
512
- let value2 = Address :: random ( ) ;
513
- assert_ne ! ( value2, Address :: mutate_interesting_word( value2, 20 , & mut runner) . unwrap( ) ) ;
514
- let value3 = Address :: random ( ) ;
515
- assert_ne ! ( value3, Address :: mutate_interesting_dword( value3, 20 , & mut runner) . unwrap( ) ) ;
385
+ let value = Word :: random ( ) ;
386
+
387
+ #[ track_caller]
388
+ fn validate_mutation ( value : Word , mutated : Option < Word > ) {
389
+ assert ! (
390
+ mutated. is_none( ) || mutated. is_some_and( |mutated| mutated != value) ,
391
+ "Mutation failed for value: {value:?}, result: {mutated:?}"
392
+ ) ;
516
393
}
517
- }
518
394
519
- #[ test]
520
- fn test_mutate_word ( ) {
521
- let mut runner = TestRunner :: new ( Config :: default ( ) ) ;
522
395
for _ in 0 ..100 {
523
- let value = Word :: random ( ) ;
524
- assert_ne ! ( value, Word :: flip_random_bit( value, 32 , & mut runner) . unwrap( ) ) ;
525
- let value1 = Word :: random ( ) ;
526
- assert_ne ! ( value1, Word :: mutate_interesting_byte( value1, 32 , & mut runner) . unwrap( ) ) ;
527
- let value2 = Word :: random ( ) ;
528
- assert_ne ! ( value2, Word :: mutate_interesting_word( value2, 32 , & mut runner) . unwrap( ) ) ;
529
- let value3 = Word :: random ( ) ;
530
- assert_ne ! ( value3, Word :: mutate_interesting_dword( value3, 32 , & mut runner) . unwrap( ) ) ;
396
+ validate_mutation ( value, Word :: flip_random_bit ( value, 32 , & mut runner) ) ;
397
+ validate_mutation ( value, Word :: mutate_interesting_byte ( value, 32 , & mut runner) ) ;
398
+ validate_mutation ( value, Word :: mutate_interesting_word ( value, 32 , & mut runner) ) ;
399
+ validate_mutation ( value, Word :: mutate_interesting_dword ( value, 32 , & mut runner) ) ;
531
400
}
532
401
}
533
402
0 commit comments