summaryrefslogtreecommitdiffstats
path: root/vendor/zip/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zip/src')
-rw-r--r--vendor/zip/src/compression.rs6
-rw-r--r--vendor/zip/src/read.rs20
-rw-r--r--vendor/zip/src/result.rs21
-rw-r--r--vendor/zip/src/spec.rs16
-rw-r--r--vendor/zip/src/types.rs91
-rw-r--r--vendor/zip/src/write.rs56
6 files changed, 135 insertions, 75 deletions
diff --git a/vendor/zip/src/compression.rs b/vendor/zip/src/compression.rs
index abd8b5300..baec93994 100644
--- a/vendor/zip/src/compression.rs
+++ b/vendor/zip/src/compression.rs
@@ -141,7 +141,7 @@ impl CompressionMethod {
impl fmt::Display for CompressionMethod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Just duplicate what the Debug format looks like, i.e, the enum key:
- write!(f, "{:?}", self)
+ write!(f, "{self:?}")
}
}
@@ -195,8 +195,8 @@ mod test {
#[test]
fn to_display_fmt() {
fn check_match(method: CompressionMethod) {
- let debug_str = format!("{:?}", method);
- let display_str = format!("{}", method);
+ let debug_str = format!("{method:?}");
+ let display_str = format!("{method}");
assert_eq!(debug_str, display_str);
}
diff --git a/vendor/zip/src/read.rs b/vendor/zip/src/read.rs
index 728ddf579..dad20c260 100644
--- a/vendor/zip/src/read.rs
+++ b/vendor/zip/src/read.rs
@@ -348,7 +348,9 @@ impl<R: Read + io::Seek> ZipArchive<R> {
Some(locator64) => {
// If we got here, this is indeed a ZIP64 file.
- if footer.disk_number as u32 != locator64.disk_with_central_directory {
+ if !footer.record_too_small()
+ && footer.disk_number as u32 != locator64.disk_with_central_directory
+ {
return unsupported_zip_error(
"Support for multi-disk files is not implemented",
);
@@ -401,7 +403,7 @@ impl<R: Read + io::Seek> ZipArchive<R> {
pub fn new(mut reader: R) -> ZipResult<ZipArchive<R>> {
let (footer, cde_start_pos) = spec::CentralDirectoryEnd::find_and_parse(&mut reader)?;
- if footer.disk_number != footer.disk_with_central_directory {
+ if !footer.record_too_small() && footer.disk_number != footer.disk_with_central_directory {
return unsupported_zip_error("Support for multi-disk files is not implemented");
}
@@ -461,7 +463,7 @@ impl<R: Read + io::Seek> ZipArchive<R> {
} else {
if let Some(p) = outpath.parent() {
if !p.exists() {
- fs::create_dir_all(&p)?;
+ fs::create_dir_all(p)?;
}
}
let mut outfile = fs::File::create(&outpath)?;
@@ -681,11 +683,11 @@ pub(crate) fn central_header_to_zip_file<R: Read + io::Seek>(
reader.read_exact(&mut file_comment_raw)?;
let file_name = match is_utf8 {
- true => String::from_utf8_lossy(&*file_name_raw).into_owned(),
+ true => String::from_utf8_lossy(&file_name_raw).into_owned(),
false => file_name_raw.clone().from_cp437(),
};
let file_comment = match is_utf8 {
- true => String::from_utf8_lossy(&*file_comment_raw).into_owned(),
+ true => String::from_utf8_lossy(&file_comment_raw).into_owned(),
false => file_comment_raw.from_cp437(),
};
@@ -920,12 +922,12 @@ impl<'a> ZipFile<'a> {
self.data.compression_method
}
- /// Get the size of the file in the archive
+ /// Get the size of the file, in bytes, in the archive
pub fn compressed_size(&self) -> u64 {
self.data.compressed_size
}
- /// Get the size of the file when uncompressed
+ /// Get the size of the file, in bytes, when uncompressed
pub fn size(&self) -> u64 {
self.data.uncompressed_size
}
@@ -1085,7 +1087,7 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(
reader.read_exact(&mut extra_field)?;
let file_name = match is_utf8 {
- true => String::from_utf8_lossy(&*file_name_raw).into_owned(),
+ true => String::from_utf8_lossy(&file_name_raw).into_owned(),
false => file_name_raw.clone().from_cp437(),
};
@@ -1129,7 +1131,7 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(
return unsupported_zip_error("The file length is not available in the local header");
}
- let limit_reader = (reader as &'a mut dyn io::Read).take(result.compressed_size as u64);
+ let limit_reader = (reader as &'a mut dyn io::Read).take(result.compressed_size);
let result_crc32 = result.crc32;
let result_compression_method = result.compression_method;
diff --git a/vendor/zip/src/result.rs b/vendor/zip/src/result.rs
index 72a30e488..00d558cb4 100644
--- a/vendor/zip/src/result.rs
+++ b/vendor/zip/src/result.rs
@@ -44,9 +44,9 @@ impl From<io::Error> for ZipError {
impl fmt::Display for ZipError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
- ZipError::Io(err) => write!(fmt, "{}", err),
- ZipError::InvalidArchive(err) => write!(fmt, "invalid Zip archive: {}", err),
- ZipError::UnsupportedArchive(err) => write!(fmt, "unsupported Zip archive: {}", err),
+ ZipError::Io(err) => write!(fmt, "{err}"),
+ ZipError::InvalidArchive(err) => write!(fmt, "invalid Zip archive: {err}"),
+ ZipError::UnsupportedArchive(err) => write!(fmt, "unsupported Zip archive: {err}"),
ZipError::FileNotFound => write!(fmt, "specified file not found in archive"),
}
}
@@ -81,3 +81,18 @@ impl From<ZipError> for io::Error {
io::Error::new(io::ErrorKind::Other, err)
}
}
+
+/// Error type for time parsing
+#[derive(Debug)]
+pub struct DateTimeRangeError;
+
+impl fmt::Display for DateTimeRangeError {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ fmt,
+ "a date could not be represented within the bounds the MS-DOS date range (1980-2107)"
+ )
+ }
+}
+
+impl Error for DateTimeRangeError {}
diff --git a/vendor/zip/src/spec.rs b/vendor/zip/src/spec.rs
index 3ffcf7323..1d8cb0a64 100644
--- a/vendor/zip/src/spec.rs
+++ b/vendor/zip/src/spec.rs
@@ -23,6 +23,18 @@ pub struct CentralDirectoryEnd {
}
impl CentralDirectoryEnd {
+ // Per spec 4.4.1.4 - a CentralDirectoryEnd field might be insufficient to hold the
+ // required data. In this case the file SHOULD contain a ZIP64 format record
+ // and the field of this record will be set to -1
+ pub(crate) fn record_too_small(&self) -> bool {
+ self.disk_number == 0xFFFF
+ || self.disk_with_central_directory == 0xFFFF
+ || self.number_of_files_on_this_disk == 0xFFFF
+ || self.number_of_files == 0xFFFF
+ || self.central_directory_size == 0xFFFFFFFF
+ || self.central_directory_offset == 0xFFFFFFFF
+ }
+
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd> {
let magic = reader.read_u32::<LittleEndian>()?;
if magic != CENTRAL_DIRECTORY_END_SIGNATURE {
@@ -64,12 +76,12 @@ impl CentralDirectoryEnd {
let mut pos = file_length - HEADER_SIZE;
while pos >= search_upper_bound {
- reader.seek(io::SeekFrom::Start(pos as u64))?;
+ reader.seek(io::SeekFrom::Start(pos))?;
if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE {
reader.seek(io::SeekFrom::Current(
BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64,
))?;
- let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?;
+ let cde_start_pos = reader.seek(io::SeekFrom::Start(pos))?;
return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
}
pos = match pos.checked_sub(1) {
diff --git a/vendor/zip/src/types.rs b/vendor/zip/src/types.rs
index b65fad401..ad3a5700b 100644
--- a/vendor/zip/src/types.rs
+++ b/vendor/zip/src/types.rs
@@ -1,13 +1,16 @@
//! Types that specify what is contained in a ZIP.
-#[cfg(doc)]
-use {crate::read::ZipFile, crate::write::FileOptions};
-
+#[cfg(feature = "time")]
+use std::convert::{TryFrom, TryInto};
#[cfg(not(any(
all(target_arch = "arm", target_pointer_width = "32"),
target_arch = "mips",
target_arch = "powerpc"
)))]
use std::sync::atomic;
+#[cfg(not(feature = "time"))]
+use std::time::SystemTime;
+#[cfg(doc)]
+use {crate::read::ZipFile, crate::write::FileOptions};
#[cfg(any(
all(target_arch = "arm", target_pointer_width = "32"),
@@ -42,9 +45,11 @@ mod atomic {
}
#[cfg(feature = "time")]
+use crate::result::DateTimeRangeError;
+#[cfg(feature = "time")]
use time::{error::ComponentRange, Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum System {
Dos = 0,
Unix = 3,
@@ -115,7 +120,7 @@ impl DateTime {
let years = (datepart & 0b1111111000000000) >> 9;
DateTime {
- year: (years + 1980) as u16,
+ year: years + 1980,
month: months as u8,
day: days as u8,
hour: hours as u8,
@@ -143,10 +148,8 @@ impl DateTime {
second: u8,
) -> Result<DateTime, ()> {
if (1980..=2107).contains(&year)
- && month >= 1
- && month <= 12
- && day >= 1
- && day <= 31
+ && (1..=12).contains(&month)
+ && (1..=31).contains(&day)
&& hour <= 23
&& minute <= 59
&& second <= 60
@@ -169,19 +172,9 @@ impl DateTime {
///
/// Returns `Err` when this object is out of bounds
#[allow(clippy::result_unit_err)]
+ #[deprecated(note = "use `DateTime::try_from()`")]
pub fn from_time(dt: OffsetDateTime) -> Result<DateTime, ()> {
- if dt.year() >= 1980 && dt.year() <= 2107 {
- Ok(DateTime {
- year: (dt.year()) as u16,
- month: (dt.month()) as u8,
- day: dt.day() as u8,
- hour: dt.hour() as u8,
- minute: dt.minute() as u8,
- second: dt.second() as u8,
- })
- } else {
- Err(())
- }
+ dt.try_into().map_err(|_err| ())
}
/// Gets the time portion of this datetime in the msdos representation
@@ -197,8 +190,6 @@ impl DateTime {
#[cfg(feature = "time")]
/// Converts the DateTime to a OffsetDateTime structure
pub fn to_time(&self) -> Result<OffsetDateTime, ComponentRange> {
- use std::convert::TryFrom;
-
let date =
Date::from_calendar_date(self.year as i32, Month::try_from(self.month)?, self.day)?;
let time = Time::from_hms(self.hour, self.minute, self.second)?;
@@ -256,6 +247,26 @@ impl DateTime {
}
}
+#[cfg(feature = "time")]
+impl TryFrom<OffsetDateTime> for DateTime {
+ type Error = DateTimeRangeError;
+
+ fn try_from(dt: OffsetDateTime) -> Result<Self, Self::Error> {
+ if dt.year() >= 1980 && dt.year() <= 2107 {
+ Ok(DateTime {
+ year: (dt.year()) as u16,
+ month: (dt.month()) as u8,
+ day: dt.day(),
+ hour: dt.hour(),
+ minute: dt.minute(),
+ second: dt.second(),
+ })
+ } else {
+ Err(DateTimeRangeError)
+ }
+ }
+}
+
pub const DEFAULT_VERSION: u8 = 46;
/// A type like `AtomicU64` except it implements `Clone` and has predefined
@@ -500,20 +511,43 @@ mod test {
#[cfg(feature = "time")]
#[test]
fn datetime_from_time_bounds() {
+ use std::convert::TryFrom;
+
+ use super::DateTime;
+ use time::macros::datetime;
+
+ // 1979-12-31 23:59:59
+ assert!(DateTime::try_from(datetime!(1979-12-31 23:59:59 UTC)).is_err());
+
+ // 1980-01-01 00:00:00
+ assert!(DateTime::try_from(datetime!(1980-01-01 00:00:00 UTC)).is_ok());
+
+ // 2107-12-31 23:59:59
+ assert!(DateTime::try_from(datetime!(2107-12-31 23:59:59 UTC)).is_ok());
+
+ // 2108-01-01 00:00:00
+ assert!(DateTime::try_from(datetime!(2108-01-01 00:00:00 UTC)).is_err());
+ }
+
+ #[cfg(feature = "time")]
+ #[test]
+ fn datetime_try_from_bounds() {
+ use std::convert::TryFrom;
+
use super::DateTime;
use time::macros::datetime;
// 1979-12-31 23:59:59
- assert!(DateTime::from_time(datetime!(1979-12-31 23:59:59 UTC)).is_err());
+ assert!(DateTime::try_from(datetime!(1979-12-31 23:59:59 UTC)).is_err());
// 1980-01-01 00:00:00
- assert!(DateTime::from_time(datetime!(1980-01-01 00:00:00 UTC)).is_ok());
+ assert!(DateTime::try_from(datetime!(1980-01-01 00:00:00 UTC)).is_ok());
// 2107-12-31 23:59:59
- assert!(DateTime::from_time(datetime!(2107-12-31 23:59:59 UTC)).is_ok());
+ assert!(DateTime::try_from(datetime!(2107-12-31 23:59:59 UTC)).is_ok());
// 2108-01-01 00:00:00
- assert!(DateTime::from_time(datetime!(2108-01-01 00:00:00 UTC)).is_err());
+ assert!(DateTime::try_from(datetime!(2108-01-01 00:00:00 UTC)).is_err());
}
#[test]
@@ -564,10 +598,11 @@ mod test {
#[test]
fn time_at_january() {
use super::DateTime;
+ use std::convert::TryFrom;
// 2020-01-01 00:00:00
let clock = OffsetDateTime::from_unix_timestamp(1_577_836_800).unwrap();
- assert!(DateTime::from_time(clock).is_ok());
+ assert!(DateTime::try_from(clock).is_ok());
}
}
diff --git a/vendor/zip/src/write.rs b/vendor/zip/src/write.rs
index 61ce378c0..14252b4d5 100644
--- a/vendor/zip/src/write.rs
+++ b/vendor/zip/src/write.rs
@@ -7,6 +7,7 @@ use crate::spec;
use crate::types::{AtomicU64, DateTime, System, ZipFileData, DEFAULT_VERSION};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use crc32fast::Hasher;
+use std::convert::TryInto;
use std::default::Default;
use std::io;
use std::io::prelude::*;
@@ -110,31 +111,6 @@ pub struct FileOptions {
}
impl FileOptions {
- /// Construct a new FileOptions object
- pub fn default() -> FileOptions {
- FileOptions {
- #[cfg(any(
- feature = "deflate",
- feature = "deflate-miniz",
- feature = "deflate-zlib"
- ))]
- compression_method: CompressionMethod::Deflated,
- #[cfg(not(any(
- feature = "deflate",
- feature = "deflate-miniz",
- feature = "deflate-zlib"
- )))]
- compression_method: CompressionMethod::Stored,
- compression_level: None,
- #[cfg(feature = "time")]
- last_modified_time: DateTime::from_time(OffsetDateTime::now_utc()).unwrap_or_default(),
- #[cfg(not(feature = "time"))]
- last_modified_time: DateTime::default(),
- permissions: None,
- large_file: false,
- }
- }
-
/// Set the compression method for the new file
///
/// The default is `CompressionMethod::Deflated`. If the deflate compression feature is
@@ -198,8 +174,29 @@ impl FileOptions {
}
impl Default for FileOptions {
+ /// Construct a new FileOptions object
fn default() -> Self {
- Self::default()
+ Self {
+ #[cfg(any(
+ feature = "deflate",
+ feature = "deflate-miniz",
+ feature = "deflate-zlib"
+ ))]
+ compression_method: CompressionMethod::Deflated,
+ #[cfg(not(any(
+ feature = "deflate",
+ feature = "deflate-miniz",
+ feature = "deflate-zlib"
+ )))]
+ compression_method: CompressionMethod::Stored,
+ compression_level: None,
+ #[cfg(feature = "time")]
+ last_modified_time: OffsetDateTime::now_utc().try_into().unwrap_or_default(),
+ #[cfg(not(feature = "time"))]
+ last_modified_time: DateTime::default(),
+ permissions: None,
+ large_file: false,
+ }
}
}
@@ -848,7 +845,7 @@ impl<W: Write + io::Seek> Drop for ZipWriter<W> {
fn drop(&mut self) {
if !self.inner.is_closed() {
if let Err(e) = self.finalize() {
- let _ = write!(io::stderr(), "ZipWriter drop failed: {:?}", e);
+ let _ = write!(io::stderr(), "ZipWriter drop failed: {e:?}");
}
}
}
@@ -1211,8 +1208,7 @@ fn validate_extra_data(file: &ZipFileData) -> ZipResult<()> {
return Err(ZipError::Io(io::Error::new(
io::ErrorKind::Other,
format!(
- "Extra data header ID {:#06} requires crate feature \"unreserved\"",
- kind,
+ "Extra data header ID {kind:#06} requires crate feature \"unreserved\"",
),
)));
}
@@ -1301,7 +1297,7 @@ fn path_to_string(path: &std::path::Path) -> String {
if !path_str.is_empty() {
path_str.push('/');
}
- path_str.push_str(&*os_str.to_string_lossy());
+ path_str.push_str(&os_str.to_string_lossy());
}
}
path_str