Skip to content

Commit

Permalink
Make StringToNumber spec compliant (#1881)
Browse files Browse the repository at this point in the history
This PR enables `StringToNumber()` to parse binary, octal and hexadecimal numbers.
  • Loading branch information
HalidOdat committed Mar 2, 2022
1 parent 3c59905 commit 7248ed1
Showing 1 changed file with 41 additions and 17 deletions.
58 changes: 41 additions & 17 deletions boa_engine/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,25 +472,49 @@ impl JsString {
pub(crate) fn string_to_number(&self) -> f64 {
let string = self.trim_matches(is_trimmable_whitespace);

// TODO: write our own lexer to match syntax StrDecimalLiteral
match string {
"" => 0.0,
"Infinity" | "+Infinity" => f64::INFINITY,
"-Infinity" => f64::NEG_INFINITY,
_ if matches!(
string
.chars()
.take(4)
.collect::<String>()
.to_ascii_lowercase()
.as_str(),
"inf" | "+inf" | "-inf" | "nan" | "+nan" | "-nan"
) =>
{
// Prevent fast_float from parsing "inf", "+inf" as Infinity and "-inf" as -Infinity
f64::NAN
"" => return 0.0,
"-Infinity" => return f64::NEG_INFINITY,
"Infinity" | "+Infinity" => return f64::INFINITY,
_ => {}
}

let mut s = string.bytes();
let base = match (s.next(), s.next()) {
(Some(b'0'), Some(b'b' | b'B')) => Some(2),
(Some(b'0'), Some(b'o' | b'O')) => Some(8),
(Some(b'0'), Some(b'x' | b'X')) => Some(16),
_ => None,
};

// Parse numbers that begin with `0b`, `0o` and `0x`.
if let Some(base) = base {
let string = &string[2..];
if string.is_empty() {
return f64::NAN;
}

// Fast path
if let Ok(value) = u32::from_str_radix(string, base) {
return f64::from(value);
}

// Slow path
let mut value = 0.0;
for c in s {
if let Some(digit) = char::from(c).to_digit(base) {
value = value * f64::from(base) + f64::from(digit);
} else {
return f64::NAN;
}
}
_ => fast_float::parse(string).unwrap_or(f64::NAN),
return value;
}

match string {
// Handle special cases so `fast_float` does not return infinity.
"inf" | "+inf" | "-inf" => f64::NAN,
string => fast_float::parse(string).unwrap_or(f64::NAN),
}
}
}
Expand Down

0 comments on commit 7248ed1

Please sign in to comment.