Fix parsing of large integers

This commit is contained in:
강동윤 2019-01-16 11:53:41 +09:00
parent bb28d81ed4
commit 338759110f
4 changed files with 43 additions and 4 deletions

View File

@ -613,7 +613,7 @@ impl<'a, I: Input> Lexer<'a, I> {
debug_assert!(count == 2 || count == 4);
let pos = self.cur_pos();
match self.read_int(16, count, raw)? {
match self.read_int_u32(16, count, raw)? {
Some(val) => match char::from_u32(val) {
Some(c) => Ok(c),
None => self.error(start, SyntaxError::NonUtf8Char { val })?,
@ -625,7 +625,7 @@ impl<'a, I: Input> Lexer<'a, I> {
/// Read `CodePoint`.
fn read_code_point(&mut self, mut raw: &mut Raw) -> LexResult<char> {
let start = self.cur_pos();
let val = self.read_int(16, 0, raw)?;
let val = self.read_int_u32(16, 0, raw)?;
match val {
Some(val) if 0x10FFFF >= val => match char::from_u32(val) {
Some(c) => Ok(c),

View File

@ -190,7 +190,30 @@ impl<'a, I: Input> Lexer<'a, I> {
/// were read, the integer value otherwise.
/// When `len` is not zero, this
/// will return `None` unless the integer has exactly `len` digits.
pub(super) fn read_int(&mut self, radix: u8, len: u8, raw: &mut Raw) -> LexResult<Option<u32>> {
pub(super) fn read_int(&mut self, radix: u8, len: u8, raw: &mut Raw) -> LexResult<Option<f64>> {
let mut count = 0;
let v = self.read_digits(
radix,
|opt: Option<f64>, radix, val| {
count += 1;
let total = opt.unwrap_or_default() * radix as f64 + val as f64;
(Some(total), count != len)
},
raw,
)?;
if len != 0 && count != len {
Ok(None)
} else {
Ok(v)
}
}
pub(super) fn read_int_u32(
&mut self,
radix: u8,
len: u8,
raw: &mut Raw,
) -> LexResult<Option<u32>> {
let mut count = 0;
let v = self.read_digits(
radix,
@ -300,7 +323,7 @@ mod tests {
fn int(radix: u8, s: &'static str) -> u32 {
lex(s, |l| {
l.read_int(radix, 0, &mut Raw(None))
l.read_int_u32(radix, 0, &mut Raw(None))
.unwrap()
.expect("read_int returned None")
})

View File

@ -891,6 +891,11 @@ fn jsx_04() {
);
}
#[test]
fn max_integer() {
lex_tokens(::Syntax::default(), "1.7976931348623157e+308");
}
#[bench]
fn lex_colors_js(b: &mut Bencher) {
b.bytes = include_str!("../../colors.js").len() as _;

View File

@ -293,3 +293,14 @@ fn array_lit() {
})
);
}
#[test]
fn max_integer() {
assert_eq_ignore_span!(
expr("1.7976931348623157e+308"),
box Expr::Lit(Lit::Num(Number {
span,
value: 1.7976931348623157e+308
}))
)
}