Skip to content

Commit

Permalink
Merge pull request #199 from yujincheng08/xz
Browse files Browse the repository at this point in the history
feat: Support XZ decompression
  • Loading branch information
Pr0methean authored Jul 5, 2024
2 parents cbdaa70 + cbd8aed commit d45bdcc
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ deflate-zlib-ng = ["flate2/zlib-ng", "deflate-flate2"]
deflate-zopfli = ["zopfli", "_deflate-any"]
lzma = ["lzma-rs/stream"]
unreserved = []
xz = ["lzma-rs/raw_decoder"]
default = [
"aes-crypto",
"bzip2",
Expand All @@ -86,6 +87,7 @@ default = [
"lzma",
"time",
"zstd",
"xz",
]

[[bench]]
Expand Down
5 changes: 4 additions & 1 deletion fuzz/fuzz.dict
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ compression_method_deflate="\x07\x00"
compression_method_deflate64="\x09\x00"
compression_method_bzip2="\x0C\x00"
compression_method_lzma="\x0E\x00"
compression_method_xz="\x5F\x00"
compression_method_zstd="]\x00"
compression_method_aes="C\x00"
xz_header_magic="\xFD7zXZ\x00"
xz_footer_magic="YZ"
extra_field_zip64="\x01\x00"
extra_field_aes="\x99\x01"
extra_field_extended_timestamp="\x55\x54"
Expand All @@ -25,4 +28,4 @@ extra_field_utf8_filename="\x75\x70"
"\xFF\xFF"
"/"
"/./"
"/../"
"/../"
10 changes: 10 additions & 0 deletions src/compression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ pub enum CompressionMethod {
/// Compress the file using LZMA
#[cfg(feature = "lzma")]
Lzma,
/// Compress the file using XZ
#[cfg(feature = "xz")]
Xz,
/// Unsupported compression method
#[cfg_attr(
not(fuzzing),
Expand Down Expand Up @@ -80,6 +83,9 @@ impl CompressionMethod {
#[cfg(not(feature = "zstd"))]
pub const ZSTD: Self = CompressionMethod::Unsupported(93);
pub const MP3: Self = CompressionMethod::Unsupported(94);
#[cfg(feature = "xz")]
pub const XZ: Self = CompressionMethod::Xz;
#[cfg(not(feature = "xz"))]
pub const XZ: Self = CompressionMethod::Unsupported(95);
pub const JPEG: Self = CompressionMethod::Unsupported(96);
pub const WAVPACK: Self = CompressionMethod::Unsupported(97);
Expand All @@ -101,6 +107,8 @@ impl CompressionMethod {
12 => CompressionMethod::Bzip2,
#[cfg(feature = "lzma")]
14 => CompressionMethod::Lzma,
#[cfg(feature = "xz")]
95 => CompressionMethod::Xz,
#[cfg(feature = "zstd")]
93 => CompressionMethod::Zstd,
#[cfg(feature = "aes-crypto")]
Expand Down Expand Up @@ -134,6 +142,8 @@ impl CompressionMethod {
CompressionMethod::Zstd => 93,
#[cfg(feature = "lzma")]
CompressionMethod::Lzma => 14,
#[cfg(feature = "xz")]
CompressionMethod::Xz => 95,
#[allow(deprecated)]
CompressionMethod::Unsupported(v) => v,
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//! | Deflate64 | ✅ | |
//! | Bzip2 | ✅ | ✅ |
//! | LZMA | ✅ | |
//! | XZ | ✅ | |
//! | AES encryption | ✅ | ✅ |
//! | ZipCrypto deprecated encryption | ✅ | ✅ |
//!
Expand Down
20 changes: 20 additions & 0 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub(crate) mod stream;
#[cfg(feature = "lzma")]
pub(crate) mod lzma;

#[cfg(feature = "xz")]
pub(crate) mod xz;

// Put the struct declaration in a private module to convince rustdoc to display ZipArchive nicely
pub(crate) mod zip_archive {
use indexmap::IndexMap;
Expand Down Expand Up @@ -122,6 +125,8 @@ use crate::aes::PWD_VERIFY_LENGTH;
use crate::extra_fields::UnicodeExtraField;
#[cfg(feature = "lzma")]
use crate::read::lzma::LzmaDecoder;
#[cfg(feature = "xz")]
use crate::read::xz::XzDecoder;
use crate::result::ZipError::{InvalidArchive, InvalidPassword, UnsupportedArchive};
use crate::spec::is_dir;
use crate::types::ffi::S_IFLNK;
Expand Down Expand Up @@ -190,6 +195,8 @@ pub(crate) enum ZipFileReader<'a> {
Zstd(Crc32Reader<ZstdDecoder<'a, io::BufReader<CryptoReader<'a>>>>),
#[cfg(feature = "lzma")]
Lzma(Crc32Reader<Box<LzmaDecoder<CryptoReader<'a>>>>),
#[cfg(feature = "xz")]
Xz(Crc32Reader<XzDecoder<CryptoReader<'a>>>),
}

impl<'a> Read for ZipFileReader<'a> {
Expand All @@ -208,6 +215,8 @@ impl<'a> Read for ZipFileReader<'a> {
ZipFileReader::Zstd(r) => r.read(buf),
#[cfg(feature = "lzma")]
ZipFileReader::Lzma(r) => r.read(buf),
#[cfg(feature = "xz")]
ZipFileReader::Xz(r) => r.read(buf),
}
}
}
Expand Down Expand Up @@ -236,6 +245,8 @@ impl<'a> ZipFileReader<'a> {
}
return;
}
#[cfg(feature = "xz")]
ZipFileReader::Xz(r) => r.into_inner().into_inner().into_inner(),
};
let _ = copy(&mut inner, &mut sink());
}
Expand Down Expand Up @@ -396,6 +407,15 @@ pub(crate) fn make_reader(
ae2_encrypted,
)))
}
#[cfg(feature = "xz")]
CompressionMethod::Xz => {
let reader = XzDecoder::new(reader);
Ok(ZipFileReader::Xz(Crc32Reader::new(
reader,
crc32,
ae2_encrypted,
)))
}
_ => Err(UnsupportedArchive("Compression method not supported")),
}
}
Expand Down
Loading

0 comments on commit d45bdcc

Please sign in to comment.