From 3fa198d8f2db8c502f64b03ba8efa17e4836bcb1 Mon Sep 17 00:00:00 2001 From: Will Brindle Date: Mon, 14 Oct 2019 16:30:17 +0100 Subject: [PATCH] core: Add extra test cases for Number function and resolve the issues they highlight --- core/src/avm1/globals.rs | 6 +++++- core/src/avm1/value.rs | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/core/src/avm1/globals.rs b/core/src/avm1/globals.rs index c19ec5571..e2bbb85d6 100644 --- a/core/src/avm1/globals.rs +++ b/core/src/avm1/globals.rs @@ -114,6 +114,7 @@ pub fn create_globals<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> } #[cfg(test)] +#[allow(clippy::unreadable_literal)] mod tests { use super::*; use crate::avm1::activation::Activation; @@ -225,6 +226,8 @@ mod tests { &[Value::String("100a".to_string())] => Value::Bool(true), &[Value::String("0x10".to_string())] => Value::Bool(false), &[Value::String("0xhello".to_string())] => Value::Bool(true), + &[Value::String("0x1999999981ffffff".to_string())] => Value::Bool(false), + &[Value::String("0xUIXUIDFKHJDF012345678".to_string())] => Value::Bool(true), &[Value::String("123e-1".to_string())] => Value::Bool(false), &[] => Value::Bool(true) ); @@ -248,7 +251,8 @@ mod tests { &[Value::String("0x10".to_string())] => Value::Number(16.0), &[Value::String("0xhello".to_string())] => Value::Number(std::f64::NAN), &[Value::String("123e-1".to_string())] => Value::Number(12.3), + &[Value::String("0x1999999981ffffff".to_string())] => Value::Number(-2113929217.0), + &[Value::String("0xUIXUIDFKHJDF012345678".to_string())] => Value::Number(std::f64::NAN), &[] => Value::Number(0.0) ); - } diff --git a/core/src/avm1/value.rs b/core/src/avm1/value.rs index e25cad93f..470126584 100644 --- a/core/src/avm1/value.rs +++ b/core/src/avm1/value.rs @@ -75,12 +75,30 @@ impl<'gc> Value<'gc> { Value::Number(v) => *v, Value::String(v) => match v.as_str() { v if v.starts_with("0x") => { - let parsed = i64::from_str_radix(&v[2..], 16); - if parsed.is_ok() { - parsed.unwrap_or_default() as f64 - } else { - std::f64::NAN + let mut n: u32 = 0; + for c in v[2..].bytes() { + n = n.wrapping_shl(4); + n |= match c { + b'0' => 0, + b'1' => 1, + b'2' => 2, + b'3' => 3, + b'4' => 4, + b'5' => 5, + b'6' => 6, + b'7' => 7, + b'8' => 8, + b'9' => 9, + b'a' | b'A' => 10, + b'b' | b'B' => 11, + b'c' | b'C' => 12, + b'd' | b'D' => 13, + b'e' | b'E' => 14, + b'f' | b'F' => 15, + _ => return NAN, + } } + f64::from(n as i32) } "" => 0.0, _ => v.parse().unwrap_or(NAN),