Bugfix - Fix overflow in duration parser (#1865)

This commit is contained in:
Finn Bear 2023-04-25 15:00:31 -07:00 committed by GitHub
parent df07bb32f5
commit b3ebd4c6b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -308,22 +308,22 @@ pub fn duration(i: &str) -> IResult<&str, Duration> {
fn duration_raw(i: &str) -> IResult<&str, Duration> {
let (i, v) = part(i)?;
let (i, u) = unit(i)?;
Ok((
i,
Duration(match u {
"ns" => time::Duration::from_nanos(v),
"µs" => time::Duration::from_micros(v),
"us" => time::Duration::from_micros(v),
"ms" => time::Duration::from_millis(v),
"s" => time::Duration::from_secs(v),
"m" => time::Duration::from_secs(v * SECONDS_PER_MINUTE),
"h" => time::Duration::from_secs(v * SECONDS_PER_HOUR),
"d" => time::Duration::from_secs(v * SECONDS_PER_DAY),
"w" => time::Duration::from_secs(v * SECONDS_PER_WEEK),
"y" => time::Duration::from_secs(v * SECONDS_PER_YEAR),
_ => time::Duration::ZERO,
}),
))
let std_duration = match u {
"ns" => Some(time::Duration::from_nanos(v)),
"µs" => Some(time::Duration::from_micros(v)),
"us" => Some(time::Duration::from_micros(v)),
"ms" => Some(time::Duration::from_millis(v)),
"s" => Some(time::Duration::from_secs(v)),
"m" => v.checked_mul(SECONDS_PER_MINUTE).map(time::Duration::from_secs),
"h" => v.checked_mul(SECONDS_PER_HOUR).map(time::Duration::from_secs),
"d" => v.checked_mul(SECONDS_PER_DAY).map(time::Duration::from_secs),
"w" => v.checked_mul(SECONDS_PER_WEEK).map(time::Duration::from_secs),
"y" => v.checked_mul(SECONDS_PER_YEAR).map(time::Duration::from_secs),
_ => unreachable!("shouldn't have parsed {u} as duration unit"),
};
std_duration.map(|d| (i, Duration(d))).ok_or(nom::Err::Error(crate::sql::Error::Parser(i)))
}
fn part(i: &str) -> IResult<&str, u64> {
@ -440,4 +440,11 @@ mod tests {
assert_eq!("500ms", format!("{}", out));
assert_eq!(out.0, Duration::new(0, 500000000));
}
#[test]
fn duration_overflow() {
let sql = "10000000000000000d";
let res = duration(sql);
assert!(res.is_err());
}
}