Update dependencies and allow for 64-bit Zopfli compression levels

This commit is contained in:
Chris Hennick 2024-02-28 16:27:03 -08:00
parent da21bbe45f
commit 007918a81f
3 changed files with 38 additions and 38 deletions

View file

@ -13,32 +13,32 @@ Library to support the reading and writing of zip files.
edition = "2021" edition = "2021"
[dependencies] [dependencies]
aes = { version = "0.8.3", optional = true } aes = { version = "0.8.4", optional = true }
byteorder = "1.4.3" byteorder = "1.5.0"
bzip2 = { version = "0.4.4", optional = true } bzip2 = { version = "0.4.4", optional = true }
chrono = { version = "0.4.26", optional = true } chrono = { version = "0.4.34", optional = true }
constant_time_eq = { version = "0.3.0", optional = true } constant_time_eq = { version = "0.3.0", optional = true }
crc32fast = "1.3.2" crc32fast = "1.4.0"
flate2 = { version = "1.0.26", default-features = false, optional = true } flate2 = { version = "1.0.28", default-features = false, optional = true }
hmac = { version = "0.12.1", optional = true, features = ["reset"] } hmac = { version = "0.12.1", optional = true, features = ["reset"] }
pbkdf2 = {version = "0.12.1", optional = true } pbkdf2 = {version = "0.12.2", optional = true }
sha1 = {version = "0.10.5", optional = true } sha1 = {version = "0.10.6", optional = true }
time = { version = "0.3.22", optional = true, default-features = false, features = ["std"] } time = { version = "0.3.34", optional = true, default-features = false, features = ["std"] }
zstd = { version = "0.12.3", optional = true, default-features = false } zstd = { version = "0.13.0", optional = true, default-features = false }
zopfli = { version = "0.7.4", optional = true } zopfli = { version = "0.8.0", optional = true }
deflate64 = { version = "0.1.5", optional = true } deflate64 = { version = "0.1.7", optional = true }
[target.'cfg(any(all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", target_arch = "powerpc"))'.dependencies] [target.'cfg(any(all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", target_arch = "powerpc"))'.dependencies]
crossbeam-utils = "0.8.16" crossbeam-utils = "0.8.19"
[target.'cfg(fuzzing)'.dependencies] [target.'cfg(fuzzing)'.dependencies]
arbitrary = { version = "1.3.0", features = ["derive"] } arbitrary = { version = "1.3.2", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
bencher = "0.1.5" bencher = "0.1.5"
getrandom = { version = "0.2.10", features = ["js"] } getrandom = { version = "0.2.12", features = ["js"] }
walkdir = "2.3.3" walkdir = "2.4.0"
time = { version = "0.3.22", features = ["formatting", "macros"] } time = { version = "0.3.34", features = ["formatting", "macros"] }
[features] [features]
aes-crypto = [ "aes", "constant_time_eq", "hmac", "pbkdf2", "sha1" ] aes-crypto = [ "aes", "constant_time_eq", "hmac", "pbkdf2", "sha1" ]

View file

@ -375,7 +375,7 @@ pub struct ZipFileData {
/// Compression method used to store the file /// Compression method used to store the file
pub compression_method: crate::compression::CompressionMethod, pub compression_method: crate::compression::CompressionMethod,
/// Compression level to store the file /// Compression level to store the file
pub compression_level: Option<i32>, pub compression_level: Option<i64>,
/// Last modified time. This will only have a 2 second precision. /// Last modified time. This will only have a 2 second precision.
pub last_modified_time: DateTime, pub last_modified_time: DateTime,
/// CRC32 checksum /// CRC32 checksum

View file

@ -22,7 +22,7 @@ use std::mem;
feature = "bzip2", feature = "bzip2",
feature = "zstd", feature = "zstd",
))] ))]
use std::num::NonZeroU8; use core::num::NonZeroU64;
use std::str::{from_utf8, Utf8Error}; use std::str::{from_utf8, Utf8Error};
use std::sync::Arc; use std::sync::Arc;
@ -152,7 +152,7 @@ struct ZipRawValues {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FileOptions { pub struct FileOptions {
pub(crate) compression_method: CompressionMethod, pub(crate) compression_method: CompressionMethod,
pub(crate) compression_level: Option<i32>, pub(crate) compression_level: Option<i64>,
pub(crate) last_modified_time: DateTime, pub(crate) last_modified_time: DateTime,
pub(crate) permissions: Option<u32>, pub(crate) permissions: Option<u32>,
pub(crate) large_file: bool, pub(crate) large_file: bool,
@ -240,7 +240,7 @@ impl FileOptions {
/// * `Zstd`: -7 - 22, with zero being mapped to default level. Default is 3 /// * `Zstd`: -7 - 22, with zero being mapped to default level. Default is 3
/// * others: only `None` is allowed /// * others: only `None` is allowed
#[must_use] #[must_use]
pub const fn compression_level(mut self, level: Option<i32>) -> FileOptions { pub const fn compression_level(mut self, level: Option<i64>) -> FileOptions {
self.compression_level = level; self.compression_level = level;
self self
} }
@ -351,7 +351,7 @@ impl FileOptions {
} }
/// Returns the compression level currently set. /// Returns the compression level currently set.
pub const fn get_compression_level(&self) -> Option<i32> { pub const fn get_compression_level(&self) -> Option<i64> {
self.compression_level self.compression_level
} }
} }
@ -1168,7 +1168,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
fn prepare_next_writer( fn prepare_next_writer(
&self, &self,
compression: CompressionMethod, compression: CompressionMethod,
compression_level: Option<i32>, compression_level: Option<i64>,
#[cfg(feature = "deflate-zopfli")] zopfli_buffer_size: Option<usize>, #[cfg(feature = "deflate-zopfli")] zopfli_buffer_size: Option<usize>,
) -> ZipResult<SwitchWriterFunction<W>> { ) -> ZipResult<SwitchWriterFunction<W>> {
if let Closed = self { if let Closed = self {
@ -1203,7 +1203,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
|| cfg!(feature = "deflate-zlib") || cfg!(feature = "deflate-zlib")
|| cfg!(feature = "deflate-zlib-ng") || cfg!(feature = "deflate-zlib-ng")
{ {
Compression::default().level() as i32 Compression::default().level() as i64
} else { } else {
24 24
}; };
@ -1221,8 +1221,8 @@ impl<W: Write + Seek> GenericZipWriter<W> {
let best_non_zopfli = Compression::best().level(); let best_non_zopfli = Compression::best().level();
if level > best_non_zopfli { if level > best_non_zopfli {
let options = Options { let options = Options {
iteration_count: NonZeroU8::try_from( iteration_count: NonZeroU64::try_from(
(level - best_non_zopfli) as u8, (level - best_non_zopfli) as u64,
) )
.unwrap(), .unwrap(),
..Default::default() ..Default::default()
@ -1268,7 +1268,7 @@ impl<W: Write + Seek> GenericZipWriter<W> {
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => { CompressionMethod::Bzip2 => {
let level = clamp_opt( let level = clamp_opt(
compression_level.unwrap_or(bzip2::Compression::default().level() as i32), compression_level.unwrap_or(bzip2::Compression::default().level() as i64),
bzip2_compression_level_range(), bzip2_compression_level_range(),
) )
.ok_or(ZipError::UnsupportedArchive( .ok_or(ZipError::UnsupportedArchive(
@ -1287,14 +1287,14 @@ impl<W: Write + Seek> GenericZipWriter<W> {
#[cfg(feature = "zstd")] #[cfg(feature = "zstd")]
CompressionMethod::Zstd => { CompressionMethod::Zstd => {
let level = clamp_opt( let level = clamp_opt(
compression_level.unwrap_or(zstd::DEFAULT_COMPRESSION_LEVEL), compression_level.unwrap_or(zstd::DEFAULT_COMPRESSION_LEVEL as i64),
zstd::compression_level_range(), zstd::compression_level_range(),
) )
.ok_or(ZipError::UnsupportedArchive( .ok_or(ZipError::UnsupportedArchive(
"Unsupported compression level", "Unsupported compression level",
))?; ))?;
Ok(Box::new(move |bare| { Ok(Box::new(move |bare| {
GenericZipWriter::Zstd(ZstdEncoder::new(bare, level).unwrap()) GenericZipWriter::Zstd(ZstdEncoder::new(bare, level as i32).unwrap())
})) }))
} }
CompressionMethod::Unsupported(..) => { CompressionMethod::Unsupported(..) => {
@ -1382,20 +1382,20 @@ impl<W: Write + Seek> GenericZipWriter<W> {
feature = "deflate-zlib-ng", feature = "deflate-zlib-ng",
feature = "deflate-zopfli" feature = "deflate-zopfli"
))] ))]
fn deflate_compression_level_range() -> std::ops::RangeInclusive<i32> { fn deflate_compression_level_range() -> std::ops::RangeInclusive<i64> {
let min = if cfg!(feature = "deflate") let min = if cfg!(feature = "deflate")
|| cfg!(feature = "deflate-miniz") || cfg!(feature = "deflate-miniz")
|| cfg!(feature = "deflate-zlib") || cfg!(feature = "deflate-zlib")
|| cfg!(feature = "deflate-zlib-ng") || cfg!(feature = "deflate-zlib-ng")
{ {
Compression::none().level() as i32 Compression::none().level() as i64
} else { } else {
Compression::best().level() as i32 + 1 Compression::best().level() as i64 + 1
}; };
let max = Compression::best().level() as i32 let max = Compression::best().level() as i64
+ if cfg!(feature = "deflate-zopfli") { + if cfg!(feature = "deflate-zopfli") {
u8::MAX as i32 u8::MAX as i64
} else { } else {
0 0
}; };
@ -1404,9 +1404,9 @@ fn deflate_compression_level_range() -> std::ops::RangeInclusive<i32> {
} }
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
fn bzip2_compression_level_range() -> std::ops::RangeInclusive<i32> { fn bzip2_compression_level_range() -> std::ops::RangeInclusive<i64> {
let min = bzip2::Compression::fast().level() as i32; let min = bzip2::Compression::fast().level() as i64;
let max = bzip2::Compression::best().level() as i32; let max = bzip2::Compression::best().level() as i64;
min..=max min..=max
} }
@ -1419,8 +1419,8 @@ fn bzip2_compression_level_range() -> std::ops::RangeInclusive<i32> {
feature = "bzip2", feature = "bzip2",
feature = "zstd" feature = "zstd"
))] ))]
fn clamp_opt<T: Ord + Copy>(value: T, range: std::ops::RangeInclusive<T>) -> Option<T> { fn clamp_opt<T: Ord + Copy, U: Ord + Copy + TryFrom<T>>(value: T, range: std::ops::RangeInclusive<U>) -> Option<T> {
if range.contains(&value) { if range.contains(&value.try_into().ok()?) {
Some(value) Some(value)
} else { } else {
None None