diff --git a/src/types.rs b/src/types.rs index 1b794cdd..6f58009c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -50,6 +50,8 @@ use crate::extra_fields::ExtraField; use crate::result::DateTimeRangeError; #[cfg(feature = "time")] use time::{error::ComponentRange, Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; +use crate::CompressionMethod; +use crate::types::ffi::S_IFDIR; #[derive(Clone, Copy, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)] #[repr(u8)] @@ -369,6 +371,7 @@ pub struct ZipFileData { } impl ZipFileData { + pub fn file_name_sanitized(&self) -> PathBuf { let no_null_filename = match self.file_name.find('\0') { Some(index) => &self.file_name[0..index], @@ -446,12 +449,34 @@ impl ZipFileData { pub const fn version_needed(&self) -> u16 { // higher versions matched first - match (self.zip64_extension(), self.compression_method) { + let compression_version: u16 = match self.compression_method { + CompressionMethod::Stored => 10, + #[cfg(feature = "_deflate-any")] + CompressionMethod::Deflated => 20, #[cfg(feature = "bzip2")] - (_, crate::compression::CompressionMethod::Bzip2) => 46, - (true, _) => 45, - _ => 20, - } + CompressionMethod::Bzip2 => 46, + #[cfg(feature = "deflate64")] + CompressionMethod::Deflate64 => 21, + #[cfg(feature = "lzma")] + CompressionMethod::Lzma => 63, + _ => DEFAULT_VERSION as u16 + }; + let crypto_version: u16 = if self.aes_mode.is_some() { + 51 + } else if self.encrypted { + 20 + } else { + 10 + }; + let misc_feature_version: u16 = if self.large_file { + 45 + } else if self.unix_mode().is_some_and(|mode| mode & S_IFDIR == S_IFDIR) { + // file is directory + 20 + } else { + 10 + }; + compression_version.max(crypto_version).max(misc_feature_version) } #[inline(always)] pub(crate) fn extra_field_len(&self) -> usize {