From 82373f9ba565160027eafc893e280aa790b500aa Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Mon, 11 Jan 2021 08:16:22 -0500 Subject: [PATCH] impl: fix signed shrinker Previously, it was possible for the signed shrinker to call abs on the minimum value of an integer. This is incorrect and can lead to a panic, so we avoid abs in that case. We add a regression test that isn't guaranteed to trip the failure but is highly likely to. Fixes #268 --- src/arbitrary.rs | 2 +- src/tester.rs | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 0adede5..13b5b65 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -813,7 +813,7 @@ macro_rules! signed_shrinker { } else { let shrinker = SignedShrinker { x: x, i: x / 2 }; let mut items = vec![0]; - if shrinker.i < 0 { + if shrinker.i < 0 && shrinker.x != <$ty>::MIN { items.push(shrinker.x.abs()); } Box::new(items.into_iter().chain(shrinker)) diff --git a/src/tester.rs b/src/tester.rs index cb6ef2e..bd0e4e6 100644 --- a/src/tester.rs +++ b/src/tester.rs @@ -431,6 +431,7 @@ mod test { let expected_argument = format!("{:?}", [true, true]); assert_eq!(failing_case.arguments, vec![expected_argument]); } + #[test] fn size_for_small_types_issue_143() { fn t(_: i8) -> bool { @@ -438,4 +439,13 @@ mod test { } QuickCheck::new().gen(Gen::new(129)).quickcheck(t as fn(i8) -> bool); } + + #[test] + fn regression_signed_shrinker_panic() { + fn foo_can_shrink(v: i8) -> bool { + let _ = crate::Arbitrary::shrink(&v); + true + } + crate::quickcheck(foo_can_shrink as fn(i8) -> bool); + } }