avm1: Don't parse "inf" as Infinity

Rust nightly 4/13 allows f64::parse to handle "infinity", case
insensitive. This broke cases such as `Number("Infinity")`, which
should return `NaN` in AVM1.

Additionally, Rust will now print "-0" for negative zero, when
previously it would print "0".

 * Return NaN for inf cases ("inf", "-Infinity", "+INF", etc.)
 * Add a test for `Number("inf")` (this was also incorrect before
   the latest nightly)
 * Add a special case for zero in `f64_to_string` to ensure
   that -0.0 gets coerced to "0".

For more info, see:
https://github.com/rust-lang/rfcs/issues/1074
This commit is contained in:
Mike Welsh 2021-04-13 02:50:03 -07:00
parent a39a1dd64f
commit b6945395a8
3 changed files with 21 additions and 4 deletions

View File

@ -1428,6 +1428,9 @@ mod tests {
["0"] => 0.0, ["0"] => 0.0,
["1"] => 1.0, ["1"] => 1.0,
["Infinity"] => f64::NAN, ["Infinity"] => f64::NAN,
["-Infinity"] => f64::NAN,
["inf"] => f64::NAN,
["-inf"] => f64::NAN,
["100a"] => f64::NAN, ["100a"] => f64::NAN,
["0xhello"] => f64::NAN, ["0xhello"] => f64::NAN,
["123e-1"] => 12.3, ["123e-1"] => 12.3,

View File

@ -180,10 +180,21 @@ impl<'gc> Value<'gc> {
f64::from(n as i32) f64::from(n as i32)
} }
"" => f64::NAN, "" => f64::NAN,
_ => v _ => {
.trim_start_matches(|c| c == '\t' || c == '\n' || c == '\r' || c == ' ') // Rust parses "inf" and "+inf" into Infinity, but Flash doesn't.
.parse() // (as of nightly 4/13, Rust also accepts "infinity")
.unwrap_or(f64::NAN), // Check if the strign starts with 'i' (ignoring any leading +/-).
if v.strip_prefix(['+', '-'].as_ref())
.unwrap_or(&v)
.starts_with(['i', 'I'].as_ref())
{
f64::NAN
} else {
v.trim_start_matches(|c| c == '\t' || c == '\n' || c == '\r' || c == ' ')
.parse()
.unwrap_or(f64::NAN)
}
}
}, },
Value::Object(_) => f64::NAN, Value::Object(_) => f64::NAN,
} }

View File

@ -22,6 +22,9 @@ pub fn f64_to_string(n: f64) -> Cow<'static, str> {
} }
} }
Cow::Owned(s) Cow::Owned(s)
} else if n == 0.0 {
// As of Rust nightly 4/13, Rust can returns an unwated "-0" for f64, which Flash doesn't want.
Cow::Borrowed("0")
} else { } else {
// Normal number. // Normal number.
Cow::Owned(n.to_string()) Cow::Owned(n.to_string())