Skip to content

Commit

Permalink
FIX: invalid block type in block switch command #12
Browse files Browse the repository at this point in the history
  • Loading branch information
ende76 committed Oct 26, 2015
1 parent 1d0df7c commit 3071fdb
Show file tree
Hide file tree
Showing 4 changed files with 33 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.13"
version = "0.3.14"
authors = ["Thomas Pickert <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/ende76/brotli-rs"
Expand Down
17 changes: 13 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ enum DecompressorError {
ExceededExpectedBytes,
InvalidBlockCountCode,
InvalidBlockSwitchCommandCode,
InvalidBlockType,
InvalidBlockTypeCode,
InvalidInsertAndCopyLengthCode,
InvalidLengthInStaticDictionary,
Expand Down Expand Up @@ -307,6 +308,7 @@ impl Error for DecompressorError {
DecompressorError::ExceededExpectedBytes => "More uncompressed bytes than expected in meta-block",
DecompressorError::InvalidBlockCountCode => "Encountered invalid value for block count code",
DecompressorError::InvalidBlockSwitchCommandCode => "Encountered invalid value for block switch command code",
DecompressorError::InvalidBlockType => "Encountered invalid value for block type",
DecompressorError::InvalidBlockTypeCode => "Encountered invalid value for block type code",
DecompressorError::InvalidInsertAndCopyLengthCode => "Encountered invalid value for insert-and-copy-length code",
DecompressorError::InvalidLengthInStaticDictionary => "Encountered invalid length in reference to static dictionary",
Expand Down Expand Up @@ -1301,15 +1303,17 @@ impl<R: Read> Decompressor<R> {
Err(_) => return Err(DecompressorError::UnexpectedEOF),
};

// debug(&format!("switch block type code = {:?}", block_type_code));

let block_type = match block_type_code {
0 => btype_prev,
1 => (btype + 1) % n_bltypes,
2...258 => block_type_code - 2,
_ => return Err(DecompressorError::InvalidBlockTypeCode),
};

if block_type >= n_bltypes {
return Err(DecompressorError::InvalidBlockType);
}

// debug(&format!("block type = {:?}", block_type));

let block_count = match self.parse_block_count(&prefix_tree_counts) {
Expand Down Expand Up @@ -1379,6 +1383,9 @@ impl<R: Read> Decompressor<R> {
};

let btype = self.meta_block.btype_l as usize;

// println!("btype = {:?}", btype);

let context_mode = self.meta_block.context_modes_literals.as_ref().unwrap()[btype];

// debug(&format!("[p1, p2] = {:?}", self.literal_buf));
Expand Down Expand Up @@ -1410,13 +1417,15 @@ impl<R: Read> Decompressor<R> {
_ => unreachable!(), // confirmed unreachable, context_mode is always read from two bits
};

// debug(&format!("(btype, cid) = {:?}", (btype, cid)));
// println!("(btype, cid) = {:?}", (btype, cid));

let index = self.meta_block.header.c_map_l.as_ref().unwrap()[btype * 64 + cid] as usize;

// debug(&format!("global bit pos = {:?}", self.in_stream.global_bit_pos));

// debug(&format!("literal prefix code index = {:?}", index));
// println!("literal prefix code index = {:?}", index);



*lit = match self.meta_block.prefix_trees_literals.as_ref().unwrap()[index].lookup_symbol(&mut self.in_stream) {
Ok(Some(symbol)) => symbol as Literal,
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 result = 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);

println!("{:?}", result);
let _ = Decompressor::new(&b"\x51\xac\x00\x48\x2f\x73\x14\x01\x14\x00\x00\x01\x00\x14\x14\xff\x00\x02\x00\x00\x00\x00\x00\x64\x14\x24\x14\x14\x14\x14\x14\x80\x00\x00\x14\xff\xff\x00\x00\x14\x14\x14\x14\x14\x14\x80\x00\x80".to_vec() as &[u8]).read_to_end(&mut input);
}
18 changes: 18 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,24 @@ fn should_reject_frewsxcv_09() {
}
}

#[test]
#[should_panic(expected="invalid value for block type")]
/// frewsxcv: fuzzer-test
/// exposes uncaught invalid block type in block switch command
/// found and reported by Corey Farwell – https://github.com/ende76/brotli-rs/issues/10
fn should_reject_frewsxcv_10() {
use std::io::Read;
use brotli::Decompressor;

let mut input = vec![];
let result = Decompressor::new(&b"\x51\xac\x00\x48\x2f\x73\x14\x01\x14\x00\x00\x01\x00\x14\x14\xff\x00\x02\x00\x00\x00\x00\x00\x64\x14\x24\x14\x14\x14\x14\x14\x80\x00\x00\x14\xff\xff\x00\x00\x14\x14\x14\x14\x14\x14\x80\x00\x80".to_vec() as &[u8]).read_to_end(&mut input);

match result {
Err(e) => panic!("{:?}", e),
_ => {},
}
}

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 3071fdb

Please sign in to comment.