Skip to content

Commit

Permalink
fuzzer fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev committed Jan 15, 2024
1 parent 09e389f commit 7bb7a3b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 26 deletions.
61 changes: 39 additions & 22 deletions fuzz/fuzz_targets/prefix.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use libfuzzer_sys::{arbitrary, fuzz_target};

use zlib::{Flush, ReturnCode};

const BYTES: &[u8] = include_bytes!("../../silesia-small.tar");

#[derive(Debug)]
struct Length(usize);

impl<'a> arbitrary::Arbitrary<'a> for Length {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
Ok(Length(u.int_in_range(0..=BYTES.len())?))
}
}

#[derive(Debug, arbitrary::Arbitrary)]
enum Level {
Zero = 0,
Expand All @@ -19,12 +28,11 @@ enum Level {
Nine = 9,
}

fuzz_target!(|input: (Level, String)| {
let (level, data) = input;
fuzz_target!(|input: (Level, Length)| {
let (level, n) = input;
let level = level as i32;

let n = n as usize % BYTES.len();
let data = &BYTES[..n];
let data = &BYTES[..n.0];

if data.len() == 0 {
return;
Expand All @@ -46,19 +54,32 @@ fuzz_target!(|input: (Level, String)| {

assert_eq!(&deflated_rs, &deflated_ng);

let output = uncompress_help(&deflated_ng[..deflated_len_ng]);
match uncompress_help(&deflated_ng) {
Err(err) => {
let raw_path = std::env::temp_dir().join("failed-inflate-raw.dat");
std::fs::write(&raw_path, &data).unwrap();

if output != data {
let path = std::env::temp_dir().join("deflate.txt");
std::fs::write(&path, &data).unwrap();
eprintln!("saved input file to {path:?}");
}
let deflated_path = std::env::temp_dir().join("failed-inflate-deflated.dat");
std::fs::write(&deflated_path, &deflated_ng).unwrap();

eprintln!("saved files\n raw: {raw_path:?}\n deflated: {deflated_path:?}");

assert_eq!(output, data);
panic!("uncompress error {:?}", err);
}
Ok(output) => {
if output != data {
let path = std::env::temp_dir().join("deflate.txt");
std::fs::write(&path, &data).unwrap();
eprintln!("saved input file to {path:?}");
}

assert_eq!(output, data);
}
}
});

fn uncompress_help(input: &[u8]) -> Vec<u8> {
let mut dest_vec = vec![0u8; 1 << 16];
fn uncompress_help(input: &[u8]) -> Result<Vec<u8>, ReturnCode> {
let mut dest_vec = vec![0u8; BYTES.len()];

let mut dest_len = dest_vec.len();
let dest = dest_vec.as_mut_ptr();
Expand All @@ -69,16 +90,12 @@ fn uncompress_help(input: &[u8]) -> Vec<u8> {
let err = unsafe { libz_ng_sys::uncompress(dest, &mut dest_len, source, source_len) };

if err != 0 {
let path = std::env::temp_dir().join("failed-inflate.txt");
std::fs::write(&path, &input).unwrap();
eprintln!("saved input file to {path:?}");
Err(zlib::ReturnCode::from(err))
} else {
dest_vec.truncate(dest_len as usize);

panic!("error {:?}", zlib::ReturnCode::from(err));
Ok(dest_vec)
}

dest_vec.truncate(dest_len as usize);

dest_vec
}

fn compress_rs(
Expand Down
11 changes: 8 additions & 3 deletions src/inflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ impl<'a> State<'a> {

if here.op == 0 {
if self.writer.remaining() == 0 {
eprintln!("self.writer.remaining == 0");
eprintln!("Ok: read_buf is full ({} bytes)", self.writer.capacity());
return self.inflate_leave(ReturnCode::Ok);
}

Expand Down Expand Up @@ -823,7 +823,10 @@ impl<'a> State<'a> {

fn match_(&mut self) -> ReturnCode {
if self.writer.remaining() == 0 {
eprintln!("self.writer.remaining == 0");
eprintln!(
"BufError: read_buf is full ({} bytes)",
self.writer.capacity()
);
return self.inflate_leave(ReturnCode::BufError);
}

Expand Down Expand Up @@ -1249,7 +1252,9 @@ fn inflate_fast_help(state: &mut State, _start: usize) -> ReturnCode {
}

let remaining = bit_reader.bytes_remaining();
if remaining.saturating_sub(INFLATE_FAST_MIN_LEFT - 1) > 0 {
if remaining.saturating_sub(INFLATE_FAST_MIN_LEFT - 1) > 0
&& writer.remaining() > INFLATE_FAST_MIN_LEFT
{
continue;
}

Expand Down
6 changes: 5 additions & 1 deletion src/read_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,11 @@ impl<'a> ReadBuf<'a> {

#[track_caller]
pub fn push(&mut self, byte: u8) {
assert!(self.remaining() >= 1, "byte must fit in remaining()");
assert!(
self.remaining() >= 1,
"read_buf is full ({} bytes)",
self.capacity()
);

self.buf[self.filled] = MaybeUninit::new(byte);

Expand Down

0 comments on commit 7bb7a3b

Please sign in to comment.