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