Bugfix - Fix overflow in duration parser (#1865)
This commit is contained in:
parent
df07bb32f5
commit
b3ebd4c6b5
1 changed files with 23 additions and 16 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue