Skip to content

Commit

Permalink
impl: fix signed shrinker
Browse files Browse the repository at this point in the history
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
  • Loading branch information
BurntSushi committed Jan 11, 2021
1 parent 40ebcc6 commit 82373f9
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
10 changes: 10 additions & 0 deletions src/tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,21 @@ 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 {
true
}
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);
}
}

0 comments on commit 82373f9

Please sign in to comment.