Ensure numbers do not overflow numeric bounds
This commit is contained in:
parent
cdef111786
commit
232b35a304
2 changed files with 26 additions and 33 deletions
|
@ -5,7 +5,6 @@ use nom::bytes::complete::tag;
|
||||||
use nom::bytes::complete::take_while;
|
use nom::bytes::complete::take_while;
|
||||||
use nom::bytes::complete::take_while_m_n;
|
use nom::bytes::complete::take_while_m_n;
|
||||||
use nom::character::is_alphanumeric;
|
use nom::character::is_alphanumeric;
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::multi::many1;
|
use nom::multi::many1;
|
||||||
use nom::Err::Error;
|
use nom::Err::Error;
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
@ -30,21 +29,6 @@ pub fn is_digit(chr: char) -> bool {
|
||||||
(0x30..=0x39).contains(&(chr as u8))
|
(0x30..=0x39).contains(&(chr as u8))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_u32(s: &str) -> u32 {
|
|
||||||
str::FromStr::from_str(s).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_u64(s: &str) -> u64 {
|
|
||||||
str::FromStr::from_str(s).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_usize(s: &str) -> usize {
|
|
||||||
str::FromStr::from_str(s).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn val_char(chr: char) -> bool {
|
pub fn val_char(chr: char) -> bool {
|
||||||
is_alphanumeric(chr as u8) || chr == '_'
|
is_alphanumeric(chr as u8) || chr == '_'
|
||||||
|
@ -61,30 +45,41 @@ pub fn escape(s: &str, f: &dyn Fn(char) -> bool, c: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_u32(i: &str) -> IResult<&str, u32> {
|
pub fn take_u32(i: &str) -> IResult<&str, u32> {
|
||||||
let (i, v) = map(take_while(is_digit), to_u32)(i)?;
|
let (i, v) = take_while(is_digit)(i)?;
|
||||||
Ok((i, v))
|
match str::FromStr::from_str(v) {
|
||||||
|
Ok(v) => Ok((i, v)),
|
||||||
|
_ => Err(Error(ParserError(i))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_u64(i: &str) -> IResult<&str, u64> {
|
pub fn take_u64(i: &str) -> IResult<&str, u64> {
|
||||||
let (i, v) = map(take_while(is_digit), to_u64)(i)?;
|
let (i, v) = take_while(is_digit)(i)?;
|
||||||
Ok((i, v))
|
match str::FromStr::from_str(v) {
|
||||||
|
Ok(v) => Ok((i, v)),
|
||||||
|
_ => Err(Error(ParserError(i))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_usize(i: &str) -> IResult<&str, usize> {
|
pub fn take_usize(i: &str) -> IResult<&str, usize> {
|
||||||
let (i, v) = map(take_while(is_digit), to_usize)(i)?;
|
let (i, v) = take_while(is_digit)(i)?;
|
||||||
Ok((i, v))
|
match str::FromStr::from_str(v) {
|
||||||
|
Ok(v) => Ok((i, v)),
|
||||||
|
_ => Err(Error(ParserError(i))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_digits(i: &str, n: usize) -> IResult<&str, u32> {
|
pub fn take_digits(i: &str, n: usize) -> IResult<&str, u32> {
|
||||||
let (i, v) = map(take_while_m_n(n, n, is_digit), to_u32)(i)?;
|
let (i, v) = take_while_m_n(n, n, is_digit)(i)?;
|
||||||
Ok((i, v))
|
match str::FromStr::from_str(v) {
|
||||||
|
Ok(v) => Ok((i, v)),
|
||||||
|
_ => Err(Error(ParserError(i))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_digits_range(i: &str, n: usize, range: impl RangeBounds<u32>) -> IResult<&str, u32> {
|
pub fn take_digits_range(i: &str, n: usize, range: impl RangeBounds<u32>) -> IResult<&str, u32> {
|
||||||
let (i, v) = map(take_while_m_n(n, n, is_digit), to_u32)(i)?;
|
let (i, v) = take_while_m_n(n, n, is_digit)(i)?;
|
||||||
if range.contains(&v) {
|
match str::FromStr::from_str(v) {
|
||||||
Ok((i, v))
|
Ok(v) if range.contains(&v) => Ok((i, v)),
|
||||||
} else {
|
_ => Err(Error(ParserError(i))),
|
||||||
Err(Error(ParserError(i)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
|
use crate::sql::common::take_u64;
|
||||||
use crate::sql::datetime::Datetime;
|
use crate::sql::datetime::Datetime;
|
||||||
use crate::sql::error::IResult;
|
use crate::sql::error::IResult;
|
||||||
use chrono::DurationRound;
|
use chrono::DurationRound;
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::is_a;
|
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize)]
|
||||||
|
@ -131,8 +130,7 @@ pub fn duration_raw(i: &str) -> IResult<&str, Duration> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part(i: &str) -> IResult<&str, u64> {
|
fn part(i: &str) -> IResult<&str, u64> {
|
||||||
let (i, v) = is_a("1234567890")(i)?;
|
let (i, v) = take_u64(i)?;
|
||||||
let v = u64::from_str(v).unwrap();
|
|
||||||
Ok((i, v))
|
Ok((i, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue