Skip to content

Commit

Permalink
FIX: caught non-positive distances #11
Browse files Browse the repository at this point in the history
  • Loading branch information
ende76 committed Oct 26, 2015
1 parent 137a0f1 commit 425d5f7
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "brotli"
version = "0.3.12"
version = "0.3.13"
authors = ["Thomas Pickert <ende.mail@web.de>"]
license = "Apache-2.0"
repository = "https://github.com/ende76/brotli-rs"
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Compression provides a <Read>-struct to wrap a Brotli-compressed stream. A consu

## Changelog

###v0.3.12 -> v0.3.13
----------------

Fixed uncaught non-positive distances. (Thanks, [Corey](https://github.com/frewsxcv)!).

###v0.3.11 -> v0.3.12
----------------

Expand Down
14 changes: 10 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ enum DecompressorError {
InvalidLengthInStaticDictionary,
InvalidMSkipLen,
InvalidTransformId,
InvalidNonPositiveDistance,
LessThanTwoNonZeroCodeLengths,
NoCodeLength,
NonZeroFillBit,
Expand Down Expand Up @@ -311,6 +312,7 @@ impl Error for DecompressorError {
DecompressorError::InvalidLengthInStaticDictionary => "Encountered invalid length in reference to static dictionary",
DecompressorError::InvalidMSkipLen => "Most significant byte of MSKIPLEN was zero",
DecompressorError::InvalidTransformId => "Encountered invalid transform id in reference to static dictionary",
DecompressorError::InvalidNonPositiveDistance => "Encountered invalid non-positive distance",
DecompressorError::LessThanTwoNonZeroCodeLengths => "Encountered invalid complex prefix code with less than two non-zero codelengths",
DecompressorError::NoCodeLength => "Encountered invalid complex prefix code with all zero codelengths",
DecompressorError::NonZeroFillBit => "Enocuntered non-zero fill bit",
Expand Down Expand Up @@ -1483,15 +1485,19 @@ impl<R: Read> Decompressor<R> {
},
Some(d @ 4...9) => {
match (self.distance_buf.nth(0), 2 * (d as i64 % 2) - 1, (d - 2) >> 1) {
(Ok(distance), sign, d) => (*distance as i64 + (sign * d as i64)) as u32,
(Ok(distance), sign, d) => match *distance as i64 + (sign * d as i64) {
distance if distance <= 0 => return Err(DecompressorError::InvalidNonPositiveDistance),
distance => distance as u32
},
(Err(_), _, _) => return Err(DecompressorError::RingBufferError),
}
},
// reference distance_buf here, to get the decoded distance
Some(d @ 10...15) => {
match (self.distance_buf.nth(1), 2 * (d as i64 % 2) - 1, (d - 8) >> 1) {
(Ok(distance), sign, d) => {
(*distance as i64 + (sign * d as i64)) as u32
(Ok(distance), sign, d) => match *distance as i64 + (sign * d as i64) {
distance if distance <= 0 => return Err(DecompressorError::InvalidNonPositiveDistance),
distance => distance as u32
},
(Err(_), _, _) => return Err(DecompressorError::RingBufferError),
}
Expand Down Expand Up @@ -1533,7 +1539,7 @@ impl<R: Read> Decompressor<R> {
None => unreachable!(), // confirmed unreachable, distance_code is always set to Some(_) at this point
};

// debug(&format!("(dc, db, d) = {:?}", (self.meta_block.distance_code, self.distance_buf.clone(), distance)));
// println!("(dc, db, d) = {:?}", (self.meta_block.distance_code, self.distance_buf.clone(), distance));

if self.meta_block.distance_code.unwrap() > 0 && distance as usize <= cmp::min(self.header.window_size.unwrap(), self.count_output) {
self.distance_buf.push(distance);
Expand Down
4 changes: 1 addition & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@ use brotli::Decompressor;

fn main() {
let mut input = vec![];
let _ = Decompressor::new(&b"\x1b\x3f\x01\xf0\x24\xb0\xc2\xa4\x80\x54\xff\xd7\x24\xb0\x12".to_vec() as &[u8]).read_to_end(&mut input);

println!("{:?}", String::from_utf8(input));
let _ = Decompressor::new(&b"\x5b\xff\x00\x01\x40\x0a\x00\xab\x16\x7b\xac\x14\x48\x4e\x73\xed\x01\x92\x03".to_vec() as &[u8]).read_to_end(&mut input);
}
12 changes: 12 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,18 @@ fn should_decompress_to_string_frewsxcv_08() {
assert_eq!(vec![88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 32, 216, 131, 217, 170, 216, 135, 217, 165, 61, 39, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 32, 1, 0, 0, 0, 3, 0, 0, 0, 61, 39, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88], input);
}

#[test]
/// frewsxcv: fuzzer-test
/// exposes uncaught non-positive distances
/// found and reported by Corey Farwell – https://github.com/ende76/brotli-rs/issues/10
fn should_decompress_frewsxcv_09() {
use std::io::Read;
use brotli::Decompressor;

let mut input = vec![];
let _ = Decompressor::new(&b"\x5b\xff\x00\x01\x40\x0a\x00\xab\x16\x7b\xac\x14\x48\x4e\x73\xed\x01\x92\x03".to_vec() as &[u8]).read_to_end(&mut input);
}

fn inverse_move_to_front_transform(v: &mut[u8]) {
let mut mtf: Vec<u8> = vec![0; 256];
let v_len = v.len();
Expand Down

0 comments on commit 425d5f7

Please sign in to comment.