X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-core%2Fsrc%2Fcompr%2Fdeflate.rs;h=638e110b8e4d4bb709712a169c925d7b15366e56;hp=89e8b6874ea4ae71005f8130fd92818697bb76eb;hb=d5d5963c3dc8356de8fdd7eafad3aabd3a9705e9;hpb=b36f412c24813b14cb2b1f8fd151863e2a49c1e2 diff --git a/nihav-core/src/compr/deflate.rs b/nihav-core/src/compr/deflate.rs index 89e8b68..638e110 100644 --- a/nihav-core/src/compr/deflate.rs +++ b/nihav-core/src/compr/deflate.rs @@ -227,6 +227,7 @@ pub struct Inflate { buf: [u8; 65536], bpos: usize, output_idx: usize, + full_pos: usize, state: InflateState, final_block: bool, @@ -305,6 +306,7 @@ impl Inflate { buf: [0; 65536], bpos: 0, output_idx: 0, + full_pos: 0, state: InflateState::Start, final_block: false, @@ -320,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. @@ -355,6 +359,7 @@ 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.is_empty() || dst.is_empty() { return Err(DecompressError::InvalidArgument); @@ -716,7 +721,8 @@ 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] != 0 && ((src[1] - 1) % 31) == 0) { 2 } else { 0 }; + inflate.decompress_data(&src[off..], dst, false) } }