diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/der/src/asn1/utc_time.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/src/asn1/utc_time.rs')
-rw-r--r-- | vendor/der/src/asn1/utc_time.rs | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/vendor/der/src/asn1/utc_time.rs b/vendor/der/src/asn1/utc_time.rs index 7c2381155..0c10e3aff 100644 --- a/vendor/der/src/asn1/utc_time.rs +++ b/vendor/der/src/asn1/utc_time.rs @@ -1,7 +1,6 @@ //! ASN.1 `UTCTime` support. use crate::{ - asn1::AnyRef, datetime::{self, DateTime}, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, @@ -12,9 +11,6 @@ use core::time::Duration; #[cfg(feature = "std")] use std::time::SystemTime; -/// Maximum year that can be represented as a `UTCTime`. -pub const MAX_YEAR: u16 = 2049; - /// ASN.1 `UTCTime` type. /// /// This type implements the validity requirements specified in @@ -37,9 +33,12 @@ impl UtcTime { /// Length of an RFC 5280-flavored ASN.1 DER-encoded [`UtcTime`]. pub const LENGTH: usize = 13; + /// Maximum year that can be represented as a `UTCTime`. + pub const MAX_YEAR: u16 = 2049; + /// Create a [`UtcTime`] from a [`DateTime`]. pub fn from_date_time(datetime: DateTime) -> Result<Self> { - if datetime.year() <= MAX_YEAR { + if datetime.year() <= UtcTime::MAX_YEAR { Ok(Self(datetime)) } else { Err(Self::TAG.value_error()) @@ -64,7 +63,6 @@ impl UtcTime { /// Instantiate from [`SystemTime`]. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn from_system_time(time: SystemTime) -> Result<Self> { DateTime::try_from(time) .map_err(|_| Self::TAG.value_error())? @@ -73,12 +71,13 @@ impl UtcTime { /// Convert to [`SystemTime`]. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn to_system_time(&self) -> SystemTime { self.0.to_system_time() } } +impl_any_conversions!(UtcTime); + impl<'a> DecodeValue<'a> for UtcTime { fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> { if Self::LENGTH != usize::try_from(header.length)? { @@ -120,7 +119,7 @@ impl EncodeValue for UtcTime { Self::LENGTH.try_into() } - fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> Result<()> { let year = match self.0.year() { y @ 1950..=1999 => y.checked_sub(1900), y @ 2000..=2049 => y.checked_sub(2000), @@ -180,18 +179,43 @@ impl TryFrom<&DateTime> for UtcTime { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl From<UtcTime> for SystemTime { fn from(utc_time: UtcTime) -> SystemTime { utc_time.to_system_time() } } -impl TryFrom<AnyRef<'_>> for UtcTime { - type Error = Error; - - fn try_from(any: AnyRef<'_>) -> Result<UtcTime> { - any.decode_into() +// Implement by hand because the derive would create invalid values. +// Use the conversion from DateTime to create a valid value. +// The DateTime type has a way bigger range of valid years than UtcTime, +// so the DateTime year is mapped into a valid range to throw away less inputs. +#[cfg(feature = "arbitrary")] +impl<'a> arbitrary::Arbitrary<'a> for UtcTime { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> { + const MIN_YEAR: u16 = 1970; + const VALID_YEAR_COUNT: u16 = UtcTime::MAX_YEAR - MIN_YEAR + 1; + const AVERAGE_SECONDS_IN_YEAR: u64 = 31_556_952; + + let datetime = DateTime::arbitrary(u)?; + let year = datetime.year(); + let duration = datetime.unix_duration(); + + // Clamp the year into a valid range to not throw away too much input + let valid_year = (year.saturating_sub(MIN_YEAR)) + .rem_euclid(VALID_YEAR_COUNT) + .saturating_add(MIN_YEAR); + let year_to_remove = year.saturating_sub(valid_year); + let valid_duration = duration + - Duration::from_secs( + u64::from(year_to_remove).saturating_mul(AVERAGE_SECONDS_IN_YEAR), + ); + + Self::from_date_time(DateTime::from_unix_duration(valid_duration).expect("supported range")) + .map_err(|_| arbitrary::Error::IncorrectFormat) + } + + fn size_hint(depth: usize) -> (usize, Option<usize>) { + DateTime::size_hint(depth) } } |