Browse Source

Make boa::parse emit error on invalid input, not panic (#807)

* make boa::parse emit error on invalid input, not panic

* formatting

* applied requested change

* formatting

* Update boa/src/syntax/lexer/number.rs

Co-authored-by: Halid Odat <halidodat@gmail.com>

* Update boa/src/syntax/lexer/number.rs

Co-authored-by: Halid Odat <halidodat@gmail.com>

* applied requested change

Co-authored-by: Halid Odat <halidodat@gmail.com>
pull/881/head
gorogoroumaru 4 years ago committed by GitHub
parent
commit
c711e404ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      boa/src/syntax/ast/op.rs
  2. 32
      boa/src/syntax/lexer/number.rs

2
boa/src/syntax/ast/op.rs

@ -602,7 +602,7 @@ pub enum CompOp {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in
In, In,
/// The `instanceop` operator returns `true` if the specified object is an instance of the /// The `instanceof` operator returns `true` if the specified object is an instance of the
/// right hand side object. /// right hand side object.
/// ///
/// Syntax: `obj instanceof Object` /// Syntax: `obj instanceof Object`

32
boa/src/syntax/lexer/number.rs

@ -157,6 +157,16 @@ impl<R> Tokenizer<R> for NumberLiteral {
// HexIntegerLiteral // HexIntegerLiteral
kind = NumericKind::Integer(16); kind = NumericKind::Integer(16);
// Checks if the next char after '0x' is a digit of that base. if not return an error.
if let Some(digit) = cursor.peek()? {
if !digit.is_digit(16) {
return Err(Error::syntax(
"expected hexadecimal digit after number base prefix",
cursor.pos(),
));
}
}
} }
'o' | 'O' => { 'o' | 'O' => {
// Remove the initial '0' from buffer. // Remove the initial '0' from buffer.
@ -165,6 +175,16 @@ impl<R> Tokenizer<R> for NumberLiteral {
// OctalIntegerLiteral // OctalIntegerLiteral
kind = NumericKind::Integer(8); kind = NumericKind::Integer(8);
// Checks if the next char after '0o' is a digit of that base. if not return an error.
if let Some(digit) = cursor.peek()? {
if !digit.is_digit(8) {
return Err(Error::syntax(
"expected hexadecimal digit after number base prefix",
cursor.pos(),
));
}
}
} }
'b' | 'B' => { 'b' | 'B' => {
// Remove the initial '0' from buffer. // Remove the initial '0' from buffer.
@ -173,6 +193,16 @@ impl<R> Tokenizer<R> for NumberLiteral {
// BinaryIntegerLiteral // BinaryIntegerLiteral
kind = NumericKind::Integer(2); kind = NumericKind::Integer(2);
// Checks if the next char after '0b' is a digit of that base. if not return an error.
if let Some(digit) = cursor.peek()? {
if !digit.is_digit(2) {
return Err(Error::syntax(
"expected hexadecimal digit after number base prefix",
cursor.pos(),
));
}
}
} }
'n' => { 'n' => {
cursor.next_char()?.expect("n character vanished"); cursor.next_char()?.expect("n character vanished");
@ -294,7 +324,7 @@ impl<R> Tokenizer<R> for NumberLiteral {
let val = f64::from_str(&buf).expect("Failed to parse float after checks"); let val = f64::from_str(&buf).expect("Failed to parse float after checks");
let int_val = val as i32; let int_val = val as i32;
// The truncated float should be identically to the non-truncated float for the conversion to be loss-less, // The truncated float should be identically to the non-truncated float for the conversion to be loss-less,
// any other different and the number must be stored as a rational. // any other different and the number must be stored as a rational.
#[allow(clippy::float_cmp)] #[allow(clippy::float_cmp)]
if (int_val as f64) == val { if (int_val as f64) == val {

Loading…
Cancel
Save