`Arbitrary::arbitrary_take_rest` can't ever decode raw data to `vec![vec![]]`
khokho opened this issue · comments
Due to the way arbitrary guesses the length of last element in take_rest
logic, there's no way to represent vec![vec![]]
using the arbitrary format.
use arbitrary::{Arbitrary, Unstructured};
fn arb(b: &[u8]) -> Vec<Vec<u8>> {
<Vec<Vec<u8>> as Arbitrary>::arbitrary_take_rest(Unstructured::new(&b)).unwrap()
}
fn main() {
println!("{:?}", arb(&[]));
println!("{:?}", arb(&[0]));
println!("{:?}", arb(&[1]));
println!("{:?}", arb(&[0, 0]));
println!("{:?}", arb(&[0, 1]));
println!("{:?}", arb(&[1, 0]));
println!("{:?}", arb(&[1, 1]));
}
output:
[]
[[0]]
[[1]]
[[], [0]]
[[], [1]]
[[0], []]
[[1], []]
I'm not sure I understand this bug report. Could you describe how the output is different from what you expect?
I wanted to say that there doesn't exist any combination of random bytes that would result in vec![vec![]]
when interpreted as Vec<Vec<u8>>
using Arbitrary
.
For example, this relatively trivial fuzzer will never find the panic case because of this issue:
#![no_main]
use libfuzzer_sys::fuzz_target;
fn run(input: Vec<Vec<u8>>) {
if input == vec![vec![]] {
panic!();
}
}
fuzz_target!(|data: Vec<Vec<u8>>| run(data));