Skip to content

Commit 0abee77

Browse files
mkruegerPr0metheanspeedy-lex
authored
feat: Add legacy shrink/reduce/implode compression (#303)
* Added legacy shrink/reduce/implode compression. * Remove the unused 0th len_count entry Signed-off-by: Chris Hennick <[email protected]> * Make legacy modules `pub(crate)` rather than `pub` Signed-off-by: Chris Hennick <[email protected]> * chore(deps): Bump MSRV to 1.83.0 for bistream-io * style: cargo fmt --all * style: cargo clippy --fix * chore: fix remaining Clippy warnings manually * style: cargo fmt --all * fix: errors introduced by fixing clippy warnings * fix: test failures on Windows due to newline style * fix: must define legacy compression methods unconditionally, for backward compatibility * style: Add missing doc comments * fix: doc comments apparently can't be before `cfg` * fix: doc comments apparently can't be before `cfg` * fix: Windows newline issues persisted (files not recognized as text?) * fix: Windows newline issues persisted (need to mark some files text and others binary) * fix?! Test a peer's suggested fix * fix use lf instead of crlf to fix tests on windows * Fix? make tests/data/legacy/*.out explicitly CRLF --------- Signed-off-by: Chris Hennick <[email protected]> Co-authored-by: Chris Hennick <[email protected]> Co-authored-by: hennickc <[email protected]> Co-authored-by: Speedy_Lex <[email protected]>
1 parent 12c87d1 commit 0abee77

24 files changed

+1484
-7
lines changed

.gitattributes

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
tests/data/** binary=true
22
tests/data/**/LICENSE.*.txt binary=false
3-
fuzz/corpus/** binary=true
3+
tests/data/folder/** binary=true
4+
tests/data/legacy/** binary=true
5+
fuzz/corpus/** binary=true
6+
7+
tests/data/folder/first.txt text eol=lf
8+
tests/data/legacy/*.out text eol=crlf

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- rustalias: stable
3535
rust: stable
3636
- rustalias: msrv
37-
rust: '1.82'
37+
rust: '1.83'
3838
- rustalias: nightly
3939
rust: nightly
4040
name: 'Build and test ${{ matrix.feature_flag }}: ${{ matrix.os }}, ${{ matrix.rustalias }}'

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repository = "https://github.com/zip-rs/zip2.git"
1212
keywords = ["zip", "archive", "compression"]
1313
# Any change to rust-version must be reflected also in `README.md` and `.github/workflows/ci.yaml`.
1414
# The MSRV policy is documented in `README.md`.
15-
rust-version = "1.82.0"
15+
rust-version = "1.83.0"
1616
description = """
1717
Library to support the reading and writing of zip files.
1818
"""
@@ -50,6 +50,7 @@ zstd = { version = "0.13", optional = true, default-features = false }
5050
zopfli = { version = "0.8", optional = true }
5151
deflate64 = { version = "0.1.9", optional = true }
5252
lzma-rust2 = { version = "0.13", optional = true, default-features = false, features = ["std", "encoder", "optimization", "xz"] }
53+
bitstream-io = { version = "4.5.0", optional = true }
5354

5455
[target.'cfg(fuzzing)'.dependencies]
5556
arbitrary = { version = "1.4.1", features = ["derive"] }
@@ -84,6 +85,7 @@ ppmd = ["dep:ppmd-rust"]
8485
unreserved = []
8586
xz = ["dep:lzma-rust2"]
8687
xz-static = ["lzma"]
88+
legacy-zip = ["bitstream-io"]
8789
default = [
8890
"aes-crypto",
8991
"bzip2",

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ By default `aes-crypto`, `bzip2`, `deflate`, `deflate64`, `lzma`, `ppmd`, `time`
5656
MSRV
5757
----
5858

59-
Our current Minimum Supported Rust Version is **1.82**. When adding features,
59+
Our current Minimum Supported Rust Version is **1.83**. When adding features,
6060
we will follow these guidelines:
6161

6262
- We will always support a minor Rust version that has been stable for at least 6 months.

src/compression.rs

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ pub enum CompressionMethod {
3838
/// Compress the file using LZMA
3939
#[cfg(feature = "lzma")]
4040
Lzma,
41+
#[cfg(feature = "legacy-zip")]
42+
/// Method 1 Shrink
43+
Shrink,
44+
#[cfg(feature = "legacy-zip")]
45+
/// Reduce (Method 2-5)
46+
Reduce(u8),
47+
#[cfg(feature = "legacy-zip")]
48+
/// Method 6 Implode/explode
49+
Implode,
4150
/// Compress the file using XZ
4251
#[cfg(feature = "xz")]
4352
Xz,
@@ -55,11 +64,40 @@ pub enum CompressionMethod {
5564
/// All compression methods defined for the ZIP format
5665
impl CompressionMethod {
5766
pub const STORE: Self = CompressionMethod::Stored;
67+
#[cfg(feature = "legacy-zip")]
68+
pub const SHRINK: Self = CompressionMethod::Shrink;
69+
#[cfg(not(feature = "legacy-zip"))]
70+
/// Legacy compression method (enable feature `legacy-zip` to get support)
5871
pub const SHRINK: Self = CompressionMethod::Unsupported(1);
72+
#[cfg(feature = "legacy-zip")]
73+
/// Legacy compression method
74+
pub const REDUCE_1: Self = CompressionMethod::Reduce(1);
75+
#[cfg(not(feature = "legacy-zip"))]
76+
/// Legacy compression method (enable feature `legacy-zip` to get support)
5977
pub const REDUCE_1: Self = CompressionMethod::Unsupported(2);
78+
#[cfg(feature = "legacy-zip")]
79+
/// Legacy compression method
80+
pub const REDUCE_2: Self = CompressionMethod::Reduce(2);
81+
#[cfg(not(feature = "legacy-zip"))]
82+
/// Legacy compression method (enable feature `legacy-zip` to get support)
6083
pub const REDUCE_2: Self = CompressionMethod::Unsupported(3);
84+
#[cfg(feature = "legacy-zip")]
85+
/// Legacy compression method
86+
pub const REDUCE_3: Self = CompressionMethod::Reduce(3);
87+
#[cfg(not(feature = "legacy-zip"))]
88+
/// Legacy compression method (enable feature `legacy-zip` to get support)
6189
pub const REDUCE_3: Self = CompressionMethod::Unsupported(4);
90+
#[cfg(feature = "legacy-zip")]
91+
/// Legacy compression method
92+
pub const REDUCE_4: Self = CompressionMethod::Reduce(4);
93+
#[cfg(not(feature = "legacy-zip"))]
94+
/// Legacy compression method (enable feature `legacy-zip` to get support)
6295
pub const REDUCE_4: Self = CompressionMethod::Unsupported(5);
96+
#[cfg(feature = "legacy-zip")]
97+
/// Legacy compression method
98+
pub const IMPLODE: Self = CompressionMethod::Implode;
99+
#[cfg(not(feature = "legacy-zip"))]
100+
/// Legacy compression method (enable feature `legacy-zip` to get support)
63101
pub const IMPLODE: Self = CompressionMethod::Unsupported(6);
64102
#[cfg(feature = "_deflate-any")]
65103
pub const DEFLATE: Self = CompressionMethod::Deflated;
@@ -105,6 +143,18 @@ impl CompressionMethod {
105143
pub(crate) const fn parse_from_u16(val: u16) -> Self {
106144
match val {
107145
0 => CompressionMethod::Stored,
146+
#[cfg(feature = "legacy-zip")]
147+
1 => CompressionMethod::Shrink,
148+
#[cfg(feature = "legacy-zip")]
149+
2 => CompressionMethod::Reduce(1),
150+
#[cfg(feature = "legacy-zip")]
151+
3 => CompressionMethod::Reduce(2),
152+
#[cfg(feature = "legacy-zip")]
153+
4 => CompressionMethod::Reduce(3),
154+
#[cfg(feature = "legacy-zip")]
155+
5 => CompressionMethod::Reduce(4),
156+
#[cfg(feature = "legacy-zip")]
157+
6 => CompressionMethod::Implode,
108158
#[cfg(feature = "_deflate-any")]
109159
8 => CompressionMethod::Deflated,
110160
#[cfg(feature = "deflate64")]
@@ -138,6 +188,13 @@ impl CompressionMethod {
138188
pub(crate) const fn serialize_to_u16(self) -> u16 {
139189
match self {
140190
CompressionMethod::Stored => 0,
191+
#[cfg(feature = "legacy-zip")]
192+
CompressionMethod::Shrink => 1,
193+
#[cfg(feature = "legacy-zip")]
194+
CompressionMethod::Reduce(n) => 1 + n as u16,
195+
#[cfg(feature = "legacy-zip")]
196+
CompressionMethod::Implode => 6,
197+
141198
#[cfg(feature = "_deflate-any")]
142199
CompressionMethod::Deflated => 8,
143200
#[cfg(feature = "deflate64")]
@@ -215,6 +272,12 @@ pub(crate) enum Decompressor<R: io::BufRead> {
215272
Zstd(zstd::Decoder<'static, R>),
216273
#[cfg(feature = "lzma")]
217274
Lzma(Lzma<R>),
275+
#[cfg(feature = "legacy-zip")]
276+
Shrink(crate::legacy::shrink::ShrinkDecoder<R>),
277+
#[cfg(feature = "legacy-zip")]
278+
Reduce(crate::legacy::reduce::ReduceDecoder<R>),
279+
#[cfg(feature = "legacy-zip")]
280+
Implode(crate::legacy::implode::ImplodeDecoder<R>),
218281
#[cfg(feature = "xz")]
219282
Xz(Box<lzma_rust2::XzReader<R>>),
220283
#[cfg(feature = "ppmd")]
@@ -338,6 +401,12 @@ impl<R: io::BufRead> io::Read for Decompressor<R> {
338401
}
339402
Ppmd::Initialized(decompressor) => decompressor.read(buf),
340403
},
404+
#[cfg(feature = "legacy-zip")]
405+
Decompressor::Shrink(r) => r.read(buf),
406+
#[cfg(feature = "legacy-zip")]
407+
Decompressor::Reduce(r) => r.read(buf),
408+
#[cfg(feature = "legacy-zip")]
409+
Decompressor::Implode(r) => r.read(buf),
341410
}
342411
}
343412
}
@@ -346,8 +415,10 @@ impl<R: io::BufRead> Decompressor<R> {
346415
pub fn new(
347416
reader: R,
348417
compression_method: CompressionMethod,
349-
#[cfg(feature = "lzma")] uncompressed_size: u64,
350-
#[cfg(not(feature = "lzma"))] _uncompressed_size: u64,
418+
#[cfg(any(feature = "lzma", feature = "legacy-zip"))] uncompressed_size: u64,
419+
#[cfg(not(any(feature = "lzma", feature = "legacy-zip")))] _uncompressed_size: u64,
420+
#[cfg(feature = "legacy-zip")] flags: u16,
421+
#[cfg(not(feature = "legacy-zip"))] _flags: u16,
351422
) -> crate::result::ZipResult<Self> {
352423
Ok(match compression_method {
353424
CompressionMethod::Stored => Decompressor::Stored(reader),
@@ -374,6 +445,18 @@ impl<R: io::BufRead> Decompressor<R> {
374445
}
375446
#[cfg(feature = "ppmd")]
376447
CompressionMethod::Ppmd => Decompressor::Ppmd(Ppmd::Uninitialized(Some(reader))),
448+
#[cfg(feature = "legacy-zip")]
449+
CompressionMethod::Shrink => Decompressor::Shrink(
450+
crate::legacy::shrink::ShrinkDecoder::new(reader, uncompressed_size),
451+
),
452+
#[cfg(feature = "legacy-zip")]
453+
CompressionMethod::Reduce(n) => Decompressor::Reduce(
454+
crate::legacy::reduce::ReduceDecoder::new(reader, uncompressed_size, n),
455+
),
456+
#[cfg(feature = "legacy-zip")]
457+
CompressionMethod::Implode => Decompressor::Implode(
458+
crate::legacy::implode::ImplodeDecoder::new(reader, uncompressed_size, flags),
459+
),
377460
_ => {
378461
return Err(crate::result::ZipError::UnsupportedArchive(
379462
"Compression method not supported",
@@ -402,6 +485,12 @@ impl<R: io::BufRead> Decompressor<R> {
402485
.ok_or_else(|| io::Error::other("Reader was not set"))?,
403486
Lzma::Initialized(decoder) => decoder.into_inner(),
404487
},
488+
#[cfg(feature = "legacy-zip")]
489+
Decompressor::Shrink(r) => r.into_inner(),
490+
#[cfg(feature = "legacy-zip")]
491+
Decompressor::Reduce(r) => r.into_inner(),
492+
#[cfg(feature = "legacy-zip")]
493+
Decompressor::Implode(r) => r.into_inner(),
405494
#[cfg(feature = "xz")]
406495
Decompressor::Xz(r) => r.into_inner(),
407496
#[cfg(feature = "ppmd")]

0 commit comments

Comments
 (0)