rust-fuzz / arbitrary

Generating structured data from arbitrary, unstructured input.

Home Page:https://docs.rs/arbitrary/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`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));