From a8b0c4f02c3e21fcf63143a0d2cf11e93e8a51e8 Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Fri, 2 Feb 2024 20:21:26 +0100 Subject: [PATCH] Re-add deflate64 support --- Cargo.lock | 7 ++++ rc-zip/Cargo.toml | 3 +- rc-zip/src/fsm/entry/deflate64_dec.rs | 47 +++++++++++++++++++++++++++ rc-zip/src/fsm/entry/deflate_dec.rs | 2 +- rc-zip/src/fsm/entry/lzma_dec.rs | 21 +++++------- rc-zip/src/fsm/entry/mod.rs | 15 +++++++++ rc-zip/src/fsm/entry/zstd_dec.rs | 21 +++++------- 7 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 rc-zip/src/fsm/entry/deflate64_dec.rs diff --git a/Cargo.lock b/Cargo.lock index 1066f14..eaa3efb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,6 +279,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "deflate64" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9576c1de19747eb6f5efb6a806c3e836512bbdb17bfedc984ccb0bcc953c8390" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -784,6 +790,7 @@ dependencies = [ "chardetng", "chrono", "crc32fast", + "deflate64", "encoding_rs", "lzma-rs", "miniz_oxide", diff --git a/rc-zip/Cargo.toml b/rc-zip/Cargo.toml index 9fe5309..9177949 100644 --- a/rc-zip/Cargo.toml +++ b/rc-zip/Cargo.toml @@ -29,6 +29,7 @@ num_enum = "0.7.2" cfg-if = "1.0.0" crc32fast = "1.3.2" miniz_oxide = { version = "0.7.1", optional = true } +deflate64 = { version = "0.1.7", optional = true } bzip2 = { version = "0.4.4", optional = true } lzma-rs = { version = "0.3.0", optional = true, features = ["stream"] } zstd = { version = "0.13.0", optional = true } @@ -36,7 +37,7 @@ zstd = { version = "0.13.0", optional = true } [features] corpus = [] deflate = ["dep:miniz_oxide"] -deflate64 = [] +deflate64 = ["dep:deflate64"] bzip2 = ["dep:bzip2"] lzma = ["dep:lzma-rs"] zstd = ["dep:zstd"] diff --git a/rc-zip/src/fsm/entry/deflate64_dec.rs b/rc-zip/src/fsm/entry/deflate64_dec.rs new file mode 100644 index 0000000..0a2cfec --- /dev/null +++ b/rc-zip/src/fsm/entry/deflate64_dec.rs @@ -0,0 +1,47 @@ +use deflate64::InflaterManaged; + +use crate::{error::Error, parse::Method}; + +use super::{DecompressOutcome, Decompressor, HasMoreInput}; + +pub(crate) struct Deflate64Dec { + inflater: InflaterManaged, +} + +impl Default for Deflate64Dec { + fn default() -> Self { + Self { + inflater: InflaterManaged::new(), + } + } +} + +impl Decompressor for Deflate64Dec { + fn decompress( + &mut self, + in_buf: &[u8], + out: &mut [u8], + _has_more_input: HasMoreInput, + ) -> Result { + tracing::trace!( + in_buf_len = in_buf.len(), + out_len = out.len(), + remain_in_internal_buffer = self.inflater.available_output(), + "decompress", + ); + + let res = self.inflater.inflate(in_buf, out); + if res.data_error { + return Err(Error::Decompression { + method: Method::Deflate64, + msg: "data error".into(), + }); + } + + let outcome = DecompressOutcome { + bytes_read: res.bytes_consumed, + bytes_written: res.bytes_written, + }; + Ok(outcome) + } +} diff --git a/rc-zip/src/fsm/entry/deflate_dec.rs b/rc-zip/src/fsm/entry/deflate_dec.rs index 48b2b22..db405b6 100644 --- a/rc-zip/src/fsm/entry/deflate_dec.rs +++ b/rc-zip/src/fsm/entry/deflate_dec.rs @@ -60,7 +60,7 @@ impl Decompressor for DeflateDec { out_len = out.len(), remain_in_internal_buffer = self.remain_in_internal_buffer, out_pos = self.out_pos, - "DeflateDec::decompress", + "decompress", ); let mut outcome: DecompressOutcome = Default::default(); diff --git a/rc-zip/src/fsm/entry/lzma_dec.rs b/rc-zip/src/fsm/entry/lzma_dec.rs index 29a5b6e..0b98890 100644 --- a/rc-zip/src/fsm/entry/lzma_dec.rs +++ b/rc-zip/src/fsm/entry/lzma_dec.rs @@ -48,7 +48,7 @@ impl Decompressor for LzmaDec { in_buf_len = in_buf.len(), out_len = out.len(), remain_in_internal_buffer = self.internal_buf_mut().len(), - "DeflateDec::decompress", + "decompress", ); let mut outcome: DecompressOutcome = Default::default(); @@ -56,7 +56,7 @@ impl Decompressor for LzmaDec { self.copy_to_out(out, &mut outcome); if outcome.bytes_written > 0 { trace!( - "LzmaDec: still draining internal buffer, just copied {} bytes", + "still draining internal buffer, just copied {} bytes", outcome.bytes_written ); return Ok(outcome); @@ -66,7 +66,7 @@ impl Decompressor for LzmaDec { State::Writing(stream) => { let n = stream.write(in_buf).map_err(dec_err)?; trace!( - "LzmaDec: wrote {} bytes to decompressor (of {} available)", + "wrote {} bytes to decompressor (of {} available)", n, in_buf.len() ); @@ -79,20 +79,20 @@ impl Decompressor for LzmaDec { // trailer after LZMA compressed data? and the decoder will _refuse_ // to let us write them, so when we have just these 10 bytes left, // it's good to just let the decoder finish up. - trace!("LzmaDec: didn't write all output AND no output yet, so keep going"); + trace!("didn't write all output AND no output yet, so keep going"); return self.decompress(&in_buf[n..], out, has_more_input); } match has_more_input { HasMoreInput::Yes => { // keep going - trace!("LzmaDec: more input to come"); + trace!("more input to come"); } HasMoreInput::No => { - trace!("LzmaDec: no more input to come"); + trace!("no more input to come"); match std::mem::take(&mut self.state) { State::Writing(stream) => { - trace!("LzmaDec: finishing..."); + trace!("finishing..."); self.state = State::Draining(stream.finish().map_err(dec_err)?); } _ => unreachable!(), @@ -107,10 +107,7 @@ impl Decompressor for LzmaDec { } self.copy_to_out(out, &mut outcome); - trace!( - "LzmaDec: decompressor gave us {} bytes", - outcome.bytes_written - ); + trace!("decompressor gave us {} bytes", outcome.bytes_written); Ok(outcome) } } @@ -137,7 +134,7 @@ impl LzmaDec { while !out.is_empty() && !internal_buf.is_empty() { let to_copy = cmp::min(out.len(), internal_buf.len()); - trace!("LzmaDec: copying {} bytes from internal buffer", to_copy); + trace!("copying {} bytes from internal buffer", to_copy); out[..to_copy].copy_from_slice(&internal_buf[..to_copy]); out = &mut out[to_copy..]; diff --git a/rc-zip/src/fsm/entry/mod.rs b/rc-zip/src/fsm/entry/mod.rs index 1f42959..8b451c0 100644 --- a/rc-zip/src/fsm/entry/mod.rs +++ b/rc-zip/src/fsm/entry/mod.rs @@ -13,6 +13,9 @@ mod store_dec; #[cfg(feature = "deflate")] mod deflate_dec; +#[cfg(feature = "deflate64")] +mod deflate64_dec; + #[cfg(feature = "bzip2")] mod bzip2_dec; @@ -317,6 +320,8 @@ enum AnyDecompressor { Store(store_dec::StoreDec), #[cfg(feature = "deflate")] Deflate(Box), + #[cfg(feature = "deflate64")] + Deflate64(Box), #[cfg(feature = "bzip2")] Bzip2(bzip2_dec::Bzip2Dec), #[cfg(feature = "lzma")] @@ -361,6 +366,14 @@ impl AnyDecompressor { return Err(err); } + #[cfg(feature = "deflate64")] + Method::Deflate64 => Self::Deflate64(Default::default()), + #[cfg(not(feature = "deflate64"))] + Method::Deflate64 => { + let err = Error::Unsupported(UnsupportedError::MethodNotEnabled(method)); + return Err(err); + } + #[cfg(feature = "bzip2")] Method::Bzip2 => Self::Bzip2(Default::default()), #[cfg(not(feature = "bzip2"))] @@ -407,6 +420,8 @@ impl Decompressor for AnyDecompressor { Self::Store(dec) => dec.decompress(in_buf, out, has_more_input), #[cfg(feature = "deflate")] Self::Deflate(dec) => dec.decompress(in_buf, out, has_more_input), + #[cfg(feature = "deflate64")] + Self::Deflate64(dec) => dec.decompress(in_buf, out, has_more_input), #[cfg(feature = "bzip2")] Self::Bzip2(dec) => dec.decompress(in_buf, out, has_more_input), #[cfg(feature = "lzma")] diff --git a/rc-zip/src/fsm/entry/zstd_dec.rs b/rc-zip/src/fsm/entry/zstd_dec.rs index e687693..276fefc 100644 --- a/rc-zip/src/fsm/entry/zstd_dec.rs +++ b/rc-zip/src/fsm/entry/zstd_dec.rs @@ -39,7 +39,7 @@ impl Decompressor for ZstdDec { in_buf_len = in_buf.len(), out_len = out.len(), remain_in_internal_buffer = self.internal_buf_mut().len(), - "DeflateDec::decompress", + "decompress", ); let mut outcome: DecompressOutcome = Default::default(); @@ -47,7 +47,7 @@ impl Decompressor for ZstdDec { self.copy_to_out(out, &mut outcome); if outcome.bytes_written > 0 { trace!( - "ZstdDec: still draining internal buffer, just copied {} bytes", + "still draining internal buffer, just copied {} bytes", outcome.bytes_written ); return Ok(outcome); @@ -57,7 +57,7 @@ impl Decompressor for ZstdDec { State::Writing(stream) => { let n = stream.write(in_buf).map_err(dec_err)?; trace!( - "ZstdDec: wrote {} bytes to decompressor (of {} available)", + "wrote {} bytes to decompressor (of {} available)", n, in_buf.len() ); @@ -70,20 +70,20 @@ impl Decompressor for ZstdDec { // trailer after LZMA compressed data? and the decoder will _refuse_ // to let us write them, so when we have just these 10 bytes left, // it's good to just let the decoder finish up. - trace!("ZstdDec: didn't write all output AND no output yet, so keep going"); + trace!("didn't write all output AND no output yet, so keep going"); return self.decompress(&in_buf[n..], out, has_more_input); } match has_more_input { HasMoreInput::Yes => { // keep going - trace!("ZstdDec: more input to come"); + trace!("more input to come"); } HasMoreInput::No => { - trace!("ZstdDec: no more input to come"); + trace!("no more input to come"); match std::mem::take(&mut self.state) { State::Writing(mut stream) => { - trace!("ZstdDec: finishing..."); + trace!("finishing..."); stream.flush().map_err(dec_err)?; self.state = State::Draining(stream.into_inner()); } @@ -99,10 +99,7 @@ impl Decompressor for ZstdDec { } self.copy_to_out(out, &mut outcome); - trace!( - "ZstdDec: decompressor gave us {} bytes", - outcome.bytes_written - ); + trace!("decompressor gave us {} bytes", outcome.bytes_written); Ok(outcome) } } @@ -129,7 +126,7 @@ impl ZstdDec { while !out.is_empty() && !internal_buf.is_empty() { let to_copy = cmp::min(out.len(), internal_buf.len()); - trace!("ZstdDec: copying {} bytes from internal buffer", to_copy); + trace!("copying {} bytes from internal buffer", to_copy); out[..to_copy].copy_from_slice(&internal_buf[..to_copy]); out = &mut out[to_copy..];