Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
Upgrade time dependency to "0.3"
Browse files Browse the repository at this point in the history
Versions of time crate prior to 0.2.23 fail audit due to RUSTSEC-2020-0071.

Crate: time
Version: 0.1.43
Title: Potential segfault in the time crate
Date: 2020-11-18
ID: RUSTSEC-2020-0071
URL: https://rustsec.org/advisories/RUSTSEC-2020-0071
Solution: Upgrade to >=0.2.23
  • Loading branch information
notmandatory committed Oct 21, 2021
1 parent 7edf248 commit e447070
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 89 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition = "2018"

[dependencies]
flate2 = { version = "1.0.0", default-features = false, optional = true }
time = { version = "0.1", optional = true }
time = { version = "0.3", features = ["formatting"], optional = true }
byteorder = "1.3"
bzip2 = { version = "0.4", optional = true }
crc32fast = "1.0"
Expand All @@ -22,6 +22,7 @@ thiserror = "1.0"
bencher = "0.1"
rand = "0.7"
walkdir = "2"
time-macros = "0.2"

[features]
deflate = ["flate2/rust_backend"]
Expand Down
121 changes: 34 additions & 87 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Types that specify what is contained in a ZIP.
#[cfg(feature = "time")]
use time::{error::ComponentRange, Date, Month, OffsetDateTime, PrimitiveDateTime, Time};

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum System {
Dos = 0,
Expand Down Expand Up @@ -117,30 +120,18 @@ impl DateTime {
}

#[cfg(feature = "time")]
/// Converts a ::time::Tm object to a DateTime
/// Converts a OffsetDateTime object to a DateTime
///
/// Returns `Err` when this object is out of bounds
pub fn from_time(tm: ::time::Tm) -> Result<DateTime, ()> {
if tm.tm_year >= 80
&& tm.tm_year <= 207
&& tm.tm_mon >= 0
&& tm.tm_mon <= 11
&& tm.tm_mday >= 1
&& tm.tm_mday <= 31
&& tm.tm_hour >= 0
&& tm.tm_hour <= 23
&& tm.tm_min >= 0
&& tm.tm_min <= 59
&& tm.tm_sec >= 0
&& tm.tm_sec <= 60
{
pub fn from_time(dt: OffsetDateTime) -> Result<DateTime, ()> {
if dt.year() >= 1980 && dt.year() <= 2107 {
Ok(DateTime {
year: (tm.tm_year + 1900) as u16,
month: (tm.tm_mon + 1) as u8,
day: tm.tm_mday as u8,
hour: tm.tm_hour as u8,
minute: tm.tm_min as u8,
second: tm.tm_sec as u8,
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(())
Expand All @@ -158,20 +149,14 @@ impl DateTime {
}

#[cfg(feature = "time")]
/// Converts the datetime to a Tm structure
///
/// The fields `tm_wday`, `tm_yday`, `tm_utcoff` and `tm_nsec` are set to their defaults.
pub fn to_time(&self) -> ::time::Tm {
::time::Tm {
tm_sec: self.second as i32,
tm_min: self.minute as i32,
tm_hour: self.hour as i32,
tm_mday: self.day as i32,
tm_mon: self.month as i32 - 1,
tm_year: self.year as i32 - 1900,
tm_isdst: -1,
..::time::empty_tm()
}
/// 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)?;
Ok(PrimitiveDateTime::new(date, time).assume_utc())
}

/// Get the year. There is no epoch, i.e. 2018 will be returned as 2018.
Expand Down Expand Up @@ -374,58 +359,26 @@ mod test {
assert!(DateTime::from_date_and_time(2107, 12, 32, 0, 0, 0).is_err());
}

#[cfg(feature = "time")]
use time::{format_description::well_known::Rfc3339, OffsetDateTime};

#[cfg(feature = "time")]
#[test]
fn datetime_from_time_bounds() {
use super::DateTime;
use time_macros::datetime;

// 1979-12-31 23:59:59
assert!(DateTime::from_time(::time::Tm {
tm_sec: 59,
tm_min: 59,
tm_hour: 23,
tm_mday: 31,
tm_mon: 11, // tm_mon has number range [0, 11]
tm_year: 79, // 1979 - 1900 = 79
..::time::empty_tm()
})
.is_err());
assert!(DateTime::from_time(datetime!(1979-12-31 23:59:59 UTC)).is_err());

// 1980-01-01 00:00:00
assert!(DateTime::from_time(::time::Tm {
tm_sec: 0,
tm_min: 0,
tm_hour: 0,
tm_mday: 1,
tm_mon: 0, // tm_mon has number range [0, 11]
tm_year: 80, // 1980 - 1900 = 80
..::time::empty_tm()
})
.is_ok());
assert!(DateTime::from_time(datetime!(1980-01-01 00:00:00 UTC)).is_ok());

// 2107-12-31 23:59:59
assert!(DateTime::from_time(::time::Tm {
tm_sec: 59,
tm_min: 59,
tm_hour: 23,
tm_mday: 31,
tm_mon: 11, // tm_mon has number range [0, 11]
tm_year: 207, // 2107 - 1900 = 207
..::time::empty_tm()
})
.is_ok());
assert!(DateTime::from_time(datetime!(2107-12-31 23:59:59 UTC)).is_ok());

// 2108-01-01 00:00:00
assert!(DateTime::from_time(::time::Tm {
tm_sec: 0,
tm_min: 0,
tm_hour: 0,
tm_mday: 1,
tm_mon: 0, // tm_mon has number range [0, 11]
tm_year: 208, // 2108 - 1900 = 208
..::time::empty_tm()
})
.is_err());
assert!(DateTime::from_time(datetime!(2108-01-01 00:00:00 UTC)).is_err());
}

#[test]
Expand All @@ -441,7 +394,7 @@ mod test {

#[cfg(feature = "time")]
assert_eq!(
format!("{}", dt.to_time().rfc3339()),
format!("{}", dt.to_time().unwrap().format(&Rfc3339).unwrap()),
"2018-11-17T10:38:30Z"
);
}
Expand All @@ -458,10 +411,7 @@ mod test {
assert_eq!(dt.second(), 62);

#[cfg(feature = "time")]
assert_eq!(
format!("{}", dt.to_time().rfc3339()),
"2107-15-31T31:63:62Z"
);
assert!(dt.to_time().is_err());

let dt = DateTime::from_msdos(0x0000, 0x0000);
assert_eq!(dt.year(), 1980);
Expand All @@ -472,10 +422,7 @@ mod test {
assert_eq!(dt.second(), 0);

#[cfg(feature = "time")]
assert_eq!(
format!("{}", dt.to_time().rfc3339()),
"1980-00-00T00:00:00Z"
);
assert!(dt.to_time().is_err());
}

#[cfg(feature = "time")]
Expand All @@ -484,8 +431,8 @@ mod test {
use super::DateTime;

// 2020-01-01 00:00:00
let clock = ::time::Timespec::new(1577836800, 0);
let tm = ::time::at_utc(clock);
assert!(DateTime::from_time(tm).is_ok());
let clock = OffsetDateTime::from_unix_timestamp(1_577_836_800).unwrap();

assert!(DateTime::from_time(clock).is_ok());
}
}
5 changes: 4 additions & 1 deletion src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use flate2::write::DeflateEncoder;
#[cfg(feature = "bzip2")]
use bzip2::write::BzEncoder;

#[cfg(feature = "time")]
use time::OffsetDateTime;

enum GenericZipWriter<W: Write + io::Seek> {
Closed,
Storer(W),
Expand Down Expand Up @@ -113,7 +116,7 @@ impl FileOptions {
)))]
compression_method: CompressionMethod::Stored,
#[cfg(feature = "time")]
last_modified_time: DateTime::from_time(time::now()).unwrap_or_default(),
last_modified_time: DateTime::from_time(OffsetDateTime::now_utc()).unwrap_or_default(),
#[cfg(not(feature = "time"))]
last_modified_time: DateTime::default(),
permissions: None,
Expand Down

0 comments on commit e447070

Please sign in to comment.