Skip to content

Commit 5755d9b

Browse files
authored
der: track reader error position in GeneralizedTime::decode_value (#2079)
1 parent d4c7f25 commit 5755d9b

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

der/src/asn1/generalized_time.rs

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,42 @@ impl GeneralizedTime {
7474

7575
impl_any_conversions!(GeneralizedTime);
7676

77+
/// Creates a [`GeneralizedTime`] from its individual, ascii
78+
/// encoded components.
79+
fn decode_from_values(
80+
year: (u8, u8, u8, u8),
81+
month: (u8, u8),
82+
day: (u8, u8),
83+
hour: (u8, u8),
84+
min: (u8, u8),
85+
sec: (u8, u8),
86+
) -> Result<GeneralizedTime> {
87+
let year = u16::from(datetime::decode_decimal(
88+
GeneralizedTime::TAG,
89+
year.0,
90+
year.1,
91+
)?)
92+
.checked_mul(100)
93+
.and_then(|y| {
94+
y.checked_add(
95+
datetime::decode_decimal(GeneralizedTime::TAG, year.2, year.3)
96+
.ok()?
97+
.into(),
98+
)
99+
})
100+
.ok_or(ErrorKind::DateTime)?;
101+
let month = datetime::decode_decimal(GeneralizedTime::TAG, month.0, month.1)?;
102+
let day = datetime::decode_decimal(GeneralizedTime::TAG, day.0, day.1)?;
103+
let hour = datetime::decode_decimal(GeneralizedTime::TAG, hour.0, hour.1)?;
104+
let minute = datetime::decode_decimal(GeneralizedTime::TAG, min.0, min.1)?;
105+
let second = datetime::decode_decimal(GeneralizedTime::TAG, sec.0, sec.1)?;
106+
107+
let dt = DateTime::new(year, month, day, hour, minute, second)
108+
.map_err(|_| GeneralizedTime::TAG.value_error())?;
109+
110+
GeneralizedTime::from_unix_duration(dt.unix_duration())
111+
}
112+
77113
impl<'a> DecodeValue<'a> for GeneralizedTime {
78114
type Error = Error;
79115

@@ -103,23 +139,15 @@ impl<'a> DecodeValue<'a> for GeneralizedTime {
103139
sec1,
104140
sec2,
105141
b'Z',
106-
] => {
107-
let year = u16::from(datetime::decode_decimal(Self::TAG, y1, y2)?)
108-
.checked_mul(100)
109-
.and_then(|y| {
110-
y.checked_add(datetime::decode_decimal(Self::TAG, y3, y4).ok()?.into())
111-
})
112-
.ok_or(ErrorKind::DateTime)?;
113-
let month = datetime::decode_decimal(Self::TAG, mon1, mon2)?;
114-
let day = datetime::decode_decimal(Self::TAG, day1, day2)?;
115-
let hour = datetime::decode_decimal(Self::TAG, hour1, hour2)?;
116-
let minute = datetime::decode_decimal(Self::TAG, min1, min2)?;
117-
let second = datetime::decode_decimal(Self::TAG, sec1, sec2)?;
118-
119-
DateTime::new(year, month, day, hour, minute, second)
120-
.map_err(|_| reader.error(Self::TAG.value_error()))
121-
.and_then(|dt| Self::from_unix_duration(dt.unix_duration()))
122-
}
142+
] => decode_from_values(
143+
(y1, y2, y3, y4),
144+
(mon1, mon2),
145+
(day1, day2),
146+
(hour1, hour2),
147+
(min1, min2),
148+
(sec1, sec2),
149+
)
150+
.map_err(|err| reader.error(err.kind())),
123151
_ => Err(reader.error(Self::TAG.value_error())),
124152
}
125153
}

0 commit comments

Comments
 (0)