X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-core%2Fsrc%2Fcompr%2Fdeflate.rs;h=3462a4034996445255b9ad0f93f79671fae12e9e;hp=8e91caa369789267c4dec7d08468cf50f244dbd6;hb=b7c882c1ce6f86c07c2340751200e3a060942826;hpb=0443d0c5f73697d5eb59081be3cde9fb02dc3e70 diff --git a/nihav-core/src/compr/deflate.rs b/nihav-core/src/compr/deflate.rs index 8e91caa..3462a40 100644 --- a/nihav-core/src/compr/deflate.rs +++ b/nihav-core/src/compr/deflate.rs @@ -72,6 +72,7 @@ impl CodebookDescReader for FixedLenCodeReader { else if idx < 280 { 7 } else { 8 } } + #[allow(clippy::identity_op)] fn code(&mut self, idx: usize) -> u32 { let base = idx as u32; let bits = self.bits(idx); @@ -226,6 +227,7 @@ pub struct Inflate { buf: [u8; 65536], bpos: usize, output_idx: usize, + full_pos: usize, state: InflateState, final_block: bool, @@ -304,6 +306,7 @@ impl Inflate { buf: [0; 65536], bpos: 0, output_idx: 0, + full_pos: 0, state: InflateState::Start, final_block: false, @@ -319,19 +322,21 @@ impl Inflate { } fn put_literal(&mut self, val: u8) { self.buf[self.bpos] = val; - self.bpos += 1; + self.bpos = (self.bpos + 1) & (self.buf.len() - 1); + self.full_pos += 1; } fn lz_copy(&mut self, offset: usize, len: usize, dst: &mut [u8]) -> DecompressResult<()> { let mask = self.buf.len() - 1; - if self.bpos < offset { + if offset > self.full_pos { return Err(DecompressError::InvalidData); } - let cstart = (self.bpos - offset) & mask; + let cstart = (self.bpos.wrapping_sub(offset)) & mask; for i in 0..len { self.buf[(self.bpos + i) & mask] = self.buf[(cstart + i) & mask]; dst[i] = self.buf[(cstart + i) & mask]; } - self.bpos += len; + self.bpos = (self.bpos + len) & mask; + self.full_pos += len; Ok(()) } ///! Reports whether decoder has finished decoding the input. @@ -354,8 +359,9 @@ impl Inflate { ///! ///! [`DecompressError::ShortData`]: ../enum.DecompressError.html#variant.ShortData ///! [`DecompressError::OutputFull`]: ../enum.DecompressError.html#variant.OutputFull + #[allow(clippy::comparison_chain)] pub fn decompress_data(&mut self, src: &[u8], dst: &mut [u8], continue_block: bool) -> DecompressResult { - if src.len() == 0 || dst.len() == 0 { + if src.is_empty() || dst.is_empty() { return Err(DecompressError::InvalidArgument); } let mut csrc = if !continue_block { @@ -597,16 +603,15 @@ impl Inflate { self.state = InflateState::End; return Err(DecompressError::InvalidHeader); } - let rpt; - if mode == 0 { - if self.cur_len_idx == 0 { - self.state = InflateState::End; - return Err(DecompressError::InvalidHeader); - } - rpt = self.all_lengths[self.cur_len_idx - 1]; - } else { - rpt = 0; - } + let rpt = if mode == 0 { + if self.cur_len_idx == 0 { + self.state = InflateState::End; + return Err(DecompressError::InvalidHeader); + } + self.all_lengths[self.cur_len_idx - 1] + } else { + 0 + }; for _ in 0..len { self.all_lengths[self.cur_len_idx] = rpt; self.cur_len_idx += 1; @@ -716,7 +721,14 @@ impl Inflate { ///! Decompresses input data into output returning the uncompressed data length. pub fn uncompress(src: &[u8], dst: &mut [u8]) -> DecompressResult { let mut inflate = Self::new(); - inflate.decompress_data(src, dst, false) + let off = if src.len() > 2 && src[0] == 0x78 && src[1] == 0x9C { 2 } else { 0 }; + inflate.decompress_data(&src[off..], dst, false) + } +} + +impl Default for Inflate { + fn default() -> Self { + Self::new() } } @@ -747,7 +759,7 @@ fn lengths_to_codes(lens: &[u8], codes: &mut [ShortCodebookDesc]) -> DecompressR *codes = ShortCodebookDesc { code: 0, bits: 0 }; } } - + Ok(()) } @@ -757,6 +769,7 @@ struct GzipCRC32 { } impl GzipCRC32 { + #[allow(clippy::unreadable_literal)] fn new() -> Self { let mut tab = [0u32; 256]; for i in 0..256 {