Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arbitrary::arbitrary_take_rest can't ever decode raw data to vec![vec![]] #158

Closed
khokho opened this issue Oct 5, 2023 · 2 comments · Fixed by #159
Closed

Arbitrary::arbitrary_take_rest can't ever decode raw data to vec![vec![]] #158

khokho opened this issue Oct 5, 2023 · 2 comments · Fixed by #159

Comments

@khokho
Copy link

khokho commented Oct 5, 2023

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], []]
@khokho khokho changed the title Arbitrary::arbitrary_take_rest can't ever represent vec![vec![]] Arbitrary::arbitrary_take_rest can't ever decode entropy to vec![vec![]] Oct 5, 2023
@khokho khokho changed the title Arbitrary::arbitrary_take_rest can't ever decode entropy to vec![vec![]] Arbitrary::arbitrary_take_rest can't ever decode raw data to vec![vec![]] Oct 5, 2023
@fitzgen
Copy link
Member

fitzgen commented Oct 10, 2023

I'm not sure I understand this bug report. Could you describe how the output is different from what you expect?

@khokho
Copy link
Author

khokho commented Oct 10, 2023

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

fitzgen added a commit to fitzgen/rust_arbitrary that referenced this issue Oct 11, 2023
…ctions

This simply makes it match the behavior of `arbitrary_iter`. I experimented with
more approaches, but I couldn't get anything that was better in terms of
balancing simplicity of implementation, ease of understanding the algorithm, and
generating all expected values.

This additionally adds a testing helper function for exhaustively generating
certain byte buffers and asserting that we generate the expected arbitrary
values from those byte buffers.

Fixes rust-fuzz#158
fitzgen added a commit to fitzgen/rust_arbitrary that referenced this issue Oct 11, 2023
…ctions

This simply makes it match the behavior of `arbitrary_iter`. I experimented with
more approaches, but I couldn't get anything that was better in terms of
balancing simplicity of implementation, ease of understanding the algorithm, and
generating all expected values.

This additionally adds a testing helper function for exhaustively generating
certain byte buffers and asserting that we generate the expected arbitrary
values from those byte buffers.

Fixes rust-fuzz#158
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants