From 4882090c1ca0007d804fb2991ee1a31b440d377b Mon Sep 17 00:00:00 2001 From: Ende Date: Sun, 25 Oct 2015 17:50:39 -0400 Subject: [PATCH] FIX: properly returned Errors instead of panicking in read(), addressing issue #3 reported by Corey Farwell --- src/lib.rs | 22 ++++++++++++++++++---- src/main.rs | 8 +++++--- tests/lib.rs | 28 +++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0f186d7..bf7218f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2275,10 +2275,24 @@ impl Read for Decompressor { fn read(&mut self, buf: &mut [u8]) -> io::Result { if self.buf.is_empty() { match self.decompress() { - Err(e) => { - - panic!(format!("{:?}", e.description())); - }, + Err(e @ DecompressorError::UnexpectedEOF) | + Err(e @ DecompressorError::NonZeroFillBit) | + Err(e @ DecompressorError::NonZeroReservedBit) | + Err(e @ DecompressorError::NonZeroTrailerBit) | + Err(e @ DecompressorError::NonZeroTrailerNibble) | + Err(e @ DecompressorError::ExpectedEndOfStream) | + Err(e @ DecompressorError::InvalidMSkipLen) | + Err(e @ DecompressorError::ParseErrorInsertAndCopyLength) | + Err(e @ DecompressorError::ParseErrorInsertLiterals) | + Err(e @ DecompressorError::ParseErrorContextMap) | + Err(e @ DecompressorError::ParseErrorDistanceCode) | + Err(e @ DecompressorError::ExceededExpectedBytes) | + Err(e @ DecompressorError::ParseErrorComplexPrefixCodeLengths) | + Err(e @ DecompressorError::RingBufferError) | + Err(e @ DecompressorError::RunLengthExceededSizeOfContextMap) | + Err(e @ DecompressorError::InvalidTransformId) | + Err(e @ DecompressorError::InvalidLengthInStaticDictionary) | + Err(e @ DecompressorError::CodeLengthsChecksum) => return Err(io::Error::new(io::ErrorKind::InvalidData, e.description())), Ok(_) => {}, } } diff --git a/src/main.rs b/src/main.rs index fca3e25..800a92d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,12 @@ extern crate brotli; fn main() { - use std::io::{ Cursor, Read }; + use std::io::Read; use brotli::Decompressor; - let mut input = vec![]; - let _ = Decompressor::new(Cursor::new(vec![0x1b, 0x3f, 0xff, 0xff, 0xdb, 0x4f, 0xe2, 0x99, 0x80, 0x12])).read_to_end(&mut input); + let mut input = vec![]; + let result = Decompressor::new(&b"\xb1".to_vec() as &[u8]).read_to_end(&mut input); + + println!("result = {:?}", result); } diff --git a/tests/lib.rs b/tests/lib.rs index efe05d2..e59192e 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -300,17 +300,39 @@ fn should_decompress_alice29_txt() { #[test] #[should_panic(expected = "Error parsing code lengths")] -/// frewsxcv: fuzzer-test +/// frewsxcv_00: fuzzer-test /// exposes endless-loop vulnerability, if runlength code lengths are not bounded by alphabet size /// found and reported by Corey Farwell – https://github.com/ende76/brotli-rs/issues/2 -fn should_reject_frewsxcv() { +fn should_reject_frewsxcv_00() { use std::io::{ Cursor, Read }; use brotli::Decompressor; let mut input = vec![]; - let _ = Decompressor::new(Cursor::new(vec![0x1b, 0x3f, 0xff, 0xff, 0xdb, 0x4f, 0xe2, 0x99, 0x80, 0x12])).read_to_end(&mut input); + let result = Decompressor::new(Cursor::new(vec![0x1b, 0x3f, 0xff, 0xff, 0xdb, 0x4f, 0xe2, 0x99, 0x80, 0x12])).read_to_end(&mut input); + + match result { + Err(e) => panic!("{:?}", e), + _ => {}, + } } +#[test] +#[should_panic(expected = "unexpected EOF")] +/// frewsxcv: fuzzer-test +/// exposes uncaught panic in read() implementation +/// found and reported by Corey Farwell – https://github.com/ende76/brotli-rs/issues/2 +fn should_reject_frewsxcv_01() { + use std::io::Read; + use brotli::Decompressor; + + let mut input = vec![]; + let result = Decompressor::new(&b"\xb1".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 = vec![0; 256];