Skip to content

Commit 8f068b5

Browse files
committed
decompress_chunked: handle larger inputs
1 parent 09f6443 commit 8f068b5

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

fuzz/fuzz_targets/decompress_chunked.rs

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
#![no_main]
2-
use libbz2_rs_sys::{BZ_FINISH, BZ_OK, BZ_STREAM_END};
2+
use libbz2_rs_sys::{BZ_FINISH, BZ_FINISH_OK, BZ_OK, BZ_STREAM_END};
33
use libfuzzer_sys::fuzz_target;
44

55
fn compress_c(data: &[u8]) -> Vec<u8> {
6-
// first, deflate the data using the standard zlib
7-
let length = 8 * 1024;
8-
let mut deflated = vec![0u8; length as usize];
6+
// First, decompress the data with the stock C bzip2.
7+
let mut output = vec![0u8; 1024];
98

109
let mut stream = bzip2_sys::bz_stream {
1110
next_in: data.as_ptr() as *mut _,
1211
avail_in: data.len() as _,
1312
total_in_lo32: 0,
1413
total_in_hi32: 0,
15-
next_out: deflated.as_mut_ptr() as *mut _,
16-
avail_out: deflated.len() as _,
14+
next_out: output.as_mut_ptr() as *mut _,
15+
avail_out: output.len() as _,
1716
total_out_lo32: 0,
1817
total_out_hi32: 0,
1918
state: std::ptr::null_mut(),
@@ -27,11 +26,32 @@ fn compress_c(data: &[u8]) -> Vec<u8> {
2726
assert_eq!(err, BZ_OK);
2827
};
2928

30-
let error = unsafe { bzip2_sys::BZ2_bzCompress(&mut stream, BZ_FINISH) };
29+
let error = loop {
30+
match unsafe { bzip2_sys::BZ2_bzCompress(&mut stream, BZ_FINISH) } {
31+
BZ_FINISH_OK => {
32+
let used = output.len() - stream.avail_out as usize;
33+
// The output buffer is full.
34+
let add_space: u32 = Ord::max(1024, output.len().try_into().unwrap());
35+
output.resize(output.len() + add_space as usize, 0);
3136

32-
assert_eq!(error, BZ_STREAM_END);
37+
// If resize() reallocates, it may have moved in memory.
38+
stream.next_out = output.as_mut_ptr().cast::<i8>().wrapping_add(used as usize);
39+
stream.avail_out += add_space;
3340

34-
deflated.truncate(
41+
continue;
42+
}
43+
BZ_STREAM_END => {
44+
break BZ_OK;
45+
}
46+
ret => {
47+
break ret;
48+
}
49+
}
50+
};
51+
52+
assert_eq!(error, BZ_OK);
53+
54+
output.truncate(
3555
((u64::from(stream.total_out_hi32) << 32) + u64::from(stream.total_out_lo32))
3656
.try_into()
3757
.unwrap(),
@@ -42,10 +62,12 @@ fn compress_c(data: &[u8]) -> Vec<u8> {
4262
assert_eq!(err, BZ_OK);
4363
}
4464

45-
deflated
65+
output
4666
}
4767

4868
fuzz_target!(|input: (String, usize)| {
69+
use libbz2_rs_sys::*;
70+
4971
let (data, chunk_size) = input;
5072

5173
if chunk_size == 0 {
@@ -54,10 +76,10 @@ fuzz_target!(|input: (String, usize)| {
5476

5577
let deflated = compress_c(data.as_bytes());
5678

57-
let mut stream = libbz2_rs_sys::bz_stream::zeroed();
79+
let mut stream = bz_stream::zeroed();
5880

5981
unsafe {
60-
let err = libbz2_rs_sys::BZ2_bzDecompressInit(&mut stream, 0, 0);
82+
let err = BZ2_bzDecompressInit(&mut stream, 0, 0);
6183
assert_eq!(err, BZ_OK);
6284
};
6385

@@ -69,13 +91,23 @@ fuzz_target!(|input: (String, usize)| {
6991
stream.next_in = chunk.as_ptr() as *mut _;
7092
stream.avail_in = chunk.len() as _;
7193

72-
let err = unsafe { libbz2_rs_sys::BZ2_bzDecompress(&mut stream) };
94+
let err = unsafe { BZ2_bzDecompress(&mut stream) };
7395
match err {
7496
BZ_OK => continue,
97+
BZ_RUN_OK => panic!("BZ_RUN_OK"),
98+
BZ_FLUSH_OK => panic!("BZ_FLUSH_OK"),
99+
BZ_FINISH_OK => panic!("BZ_FINISH_OK"),
75100
BZ_STREAM_END => continue,
76-
_ => {
77-
panic!("{err}");
78-
}
101+
BZ_SEQUENCE_ERROR => panic!("BZ_SEQUENCE_ERROR"),
102+
BZ_PARAM_ERROR => panic!("BZ_PARAM_ERROR"),
103+
BZ_MEM_ERROR => panic!("BZ_MEM_ERROR"),
104+
BZ_DATA_ERROR => panic!("BZ_DATA_ERROR"),
105+
BZ_DATA_ERROR_MAGIC => panic!("BZ_DATA_ERROR_MAGIC"),
106+
BZ_IO_ERROR => panic!("BZ_IO_ERROR"),
107+
BZ_UNEXPECTED_EOF => panic!("BZ_UNEXPECTED_EOF"),
108+
BZ_OUTBUFF_FULL => panic!("BZ_OUTBUFF_FULL"),
109+
BZ_CONFIG_ERROR => panic!("BZ_CONFIG_ERROR"),
110+
_ => panic!("{err}"),
79111
}
80112
}
81113

@@ -87,7 +119,7 @@ fuzz_target!(|input: (String, usize)| {
87119
let output = String::from_utf8(output).unwrap();
88120

89121
unsafe {
90-
let err = libbz2_rs_sys::BZ2_bzDecompressEnd(&mut stream);
122+
let err = BZ2_bzDecompressEnd(&mut stream);
91123
assert_eq!(err, BZ_OK);
92124
}
93125

0 commit comments

Comments
 (0)