diff --git a/Cargo.lock b/Cargo.lock index c7f9ebb699..a3cf971b01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cd65a4b849ace0b7f6daeebcc1a1d111282227ca745458c61dbf670e52a597" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -74,15 +74,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -98,9 +98,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0238ca56c96dfa37bdf7c373c8886dd591322500aceeeccdb2216fe06dc2f796" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -122,15 +122,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener 2.5.3", + "event-listener", "futures-core", ] [[package]] name = "async-executor" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f2db9467baa66a700abce2a18c5ad793f6f83310aca1284796fc3921d113fd" +checksum = "2c1da3ae8dabd9c00f453a329dfe1fb28da3c0a72e2478cdcd93171740c20499" dependencies = [ "async-lock", "async-task", @@ -166,7 +166,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.23", + "rustix 0.37.24", "slab", "socket2", "waker-fn", @@ -178,7 +178,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener 2.5.3", + "event-listener", ] [[package]] @@ -194,37 +194,19 @@ dependencies = [ [[package]] name = "async-process" -version = "1.8.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf012553ce51eb7aa6dc2143804cc8252bd1cb681a1c5cb7fa94ca88682dee1d" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" dependencies = [ "async-io", "async-lock", - "async-signal", + "autocfg", "blocking", "cfg-if", - "event-listener 3.0.0", + "event-listener", "futures-lite", - "rustix 0.38.14", - "windows-sys 0.48.0", -] - -[[package]] -name = "async-signal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af361a844928cb7d36590d406709473a1b574f443094422ef166daa3b493208" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "concurrent-queue", - "futures-core", - "futures-io", - "libc", - "signal-hook-registry", - "slab", + "rustix 0.37.24", + "signal-hook", "windows-sys 0.48.0", ] @@ -998,6 +980,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + [[package]] name = "endian-type" version = "0.1.2" @@ -1021,9 +1009,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", @@ -1056,17 +1044,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "event-listener" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - [[package]] name = "eyre" version = "0.6.8" @@ -1105,7 +1082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", - "rustix 0.38.14", + "rustix 0.38.17", "windows-sys 0.48.0", ] @@ -1336,12 +1313,11 @@ dependencies = [ [[package]] name = "icu_codepointtrie_builder" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f848e681eee3907b3a5ecda6f1e6ce47e50cbafad37c5e85d2135e52bc481e80" +checksum = "872a3fcc14248bb28572e1340fc23c14c0bcc083d1660743a76c4121e7fcb859" dependencies = [ "icu_collections", - "lazy_static", "toml 0.5.11", ] @@ -1381,9 +1357,9 @@ dependencies = [ [[package]] name = "icu_datagen" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ec4916c5bc6843fa7789888dee44fc72cf5565352a8ba9851fe531848adb7ef" +checksum = "1cdad9848f19a7b00f64cd28bb8f16113f54212323c5be9f9da5238cbb6611b6" dependencies = [ "displaydoc", "elsa", @@ -1601,9 +1577,9 @@ dependencies = [ [[package]] name = "icu_provider_adapters" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb43949fa871c2c79828575058971af57b0ac5e58c9e4fdb69f1f4a2f3f4e17" +checksum = "36b380ef2d3d93b015cd0563d7e0d005cc07f82a5503716dbc191798d0079e1d" dependencies = [ "icu_locid", "icu_locid_transform", @@ -1731,7 +1707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.14", + "rustix 0.38.17", "windows-sys 0.48.0", ] @@ -1814,9 +1790,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "litemap" @@ -1869,9 +1845,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" @@ -2249,11 +2225,12 @@ checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" [[package]] name = "postcard" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d534c6e61df1c7166e636ca612d9820d486fe96ddad37f7abc671517b297488e" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" dependencies = [ "cobs", + "embedded-io", "serde", ] @@ -2459,9 +2436,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.23" +version = "0.37.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "4279d76516df406a8bd37e7dff53fd37d1a093f997a3c34a5c21658c126db06d" dependencies = [ "bitflags 1.3.2", "errno", @@ -2473,14 +2450,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.7", + "linux-raw-sys 0.4.8", "windows-sys 0.48.0", ] @@ -2492,20 +2469,10 @@ checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.6", + "rustls-webpki", "sct", ] -[[package]] -name = "rustls-webpki" -version = "0.100.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.101.6" @@ -2565,9 +2532,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "ryu-js" -version = "0.2.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" +checksum = "4950d85bc52415f8432144c97c4791bd0c4f7954de32a7270ee9cccd3c22b12b" [[package]] name = "same-file" @@ -2670,9 +2637,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2984,9 +2951,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07bb54ef1f8ff27564b08b861144d3b8d40263efe07684f64987f4c0d044e3e" +checksum = "d5d0e245e80bdc9b4e5356fc45a72184abbc3861992603f515270e9340f5a219" dependencies = [ "databake", "displaydoc", @@ -3199,16 +3166,16 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "ureq" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ "base64", "flate2", "log", "once_cell", "rustls", - "rustls-webpki 0.100.3", + "rustls-webpki", "url", "webpki-roots", ] @@ -3342,12 +3309,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.3", -] +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "winapi" diff --git a/boa_engine/Cargo.toml b/boa_engine/Cargo.toml index 9fba40a838..6b58a20ef0 100644 --- a/boa_engine/Cargo.toml +++ b/boa_engine/Cargo.toml @@ -66,7 +66,7 @@ num-bigint = { workspace = true, features = ["serde"] } num-integer = "0.1.45" bitflags.workspace = true indexmap = { workspace = true, features = ["std"] } -ryu-js = "0.2.2" +ryu-js = "1.0.0" chrono = { workspace = true, default-features = false, features = ["clock", "std"] } fast-float.workspace = true once_cell = { workspace = true, features = ["std"] } diff --git a/boa_engine/src/builtins/number/mod.rs b/boa_engine/src/builtins/number/mod.rs index 5a98a89b9e..4598df8795 100644 --- a/boa_engine/src/builtins/number/mod.rs +++ b/boa_engine/src/builtins/number/mod.rs @@ -277,20 +277,12 @@ impl Number { .ok_or_else(|| { JsNativeError::range() .with_message("toFixed() digits argument must be between 0 and 100") - })? as usize; + })? as u8; - // 6. If x is not finite, return ! Number::toString(x). - if !this_num.is_finite() { - Ok(JsValue::new(Self::to_js_string(this_num))) - // 10. If x ≥ 10^21, then let m be ! ToString(𝔽(x)). - } else if this_num >= 1.0e21 { - Ok(JsValue::new(f64_to_exponential(this_num))) - } else { - // Get rid of the '-' sign for -0.0 because of 9. If x < 0, then set s to "-". - let this_num = if this_num == 0_f64 { 0_f64 } else { this_num }; - let this_fixed_num = format!("{this_num:.precision$}"); - Ok(JsValue::new(js_string!(this_fixed_num))) - } + let mut buffer = ryu_js::Buffer::new(); + let string = buffer.format_to_fixed(this_num, precision); + + Ok(js_string!(string).into()) } /// `Number.prototype.toLocaleString( [locales [, options]] )` diff --git a/boa_engine/src/builtins/number/tests.rs b/boa_engine/src/builtins/number/tests.rs index d44ef4ba4d..290c4fb9a2 100644 --- a/boa_engine/src/builtins/number/tests.rs +++ b/boa_engine/src/builtins/number/tests.rs @@ -48,6 +48,122 @@ fn to_fixed() { "Number('I am also not a number').toFixed()", js_string!("NaN"), ), + TestAction::assert_eq("(1.35).toFixed(1)", js_string!("1.4")), + // Test cases from https://source.chromium.org/chromium/chromium/src/+/main:v8/test/mjsunit/number-tostring-func.js;l=157-240;drc=aa3518a0f37245ebe8f062dce97ee492e2a41652 + TestAction::assert_eq("(NaN).toFixed(2)", js_string!("NaN")), + TestAction::assert_eq("(1/0).toFixed(2)", js_string!("Infinity")), + TestAction::assert_eq("(-1/0).toFixed(2)", js_string!("-Infinity")), + TestAction::assert_eq( + "(1111111111111111111111).toFixed(8)", + js_string!("1.1111111111111111e+21"), + ), + TestAction::assert_eq("(0.1).toFixed(1)", js_string!("0.1")), + TestAction::assert_eq("(0.1).toFixed(2)", js_string!("0.10")), + TestAction::assert_eq("(0.1).toFixed(3)", js_string!("0.100")), + TestAction::assert_eq("(0.01).toFixed(2)", js_string!("0.01")), + TestAction::assert_eq("(0.01).toFixed(3)", js_string!("0.010")), + TestAction::assert_eq("(0.01).toFixed(4)", js_string!("0.0100")), + TestAction::assert_eq("(0.001).toFixed(2)", js_string!("0.00")), + TestAction::assert_eq("(0.001).toFixed(3)", js_string!("0.001")), + TestAction::assert_eq("(0.001).toFixed(4)", js_string!("0.0010")), + TestAction::assert_eq("(1).toFixed(4)", js_string!("1.0000")), + TestAction::assert_eq("(1).toFixed(1)", js_string!("1.0")), + TestAction::assert_eq("(1).toFixed(0)", js_string!("1")), + TestAction::assert_eq("(12).toFixed(0)", js_string!("12")), + TestAction::assert_eq("(1.1).toFixed(0)", js_string!("1")), + TestAction::assert_eq("(12.1).toFixed(0)", js_string!("12")), + TestAction::assert_eq("(1.12).toFixed(0)", js_string!("1")), + TestAction::assert_eq("(12.12).toFixed(0)", js_string!("12")), + TestAction::assert_eq("(0.0000006).toFixed(7)", js_string!("0.0000006")), + TestAction::assert_eq("(0.00000006).toFixed(8)", js_string!("0.00000006")), + TestAction::assert_eq("(0.00000006).toFixed(9)", js_string!("0.000000060")), + TestAction::assert_eq("(0.00000006).toFixed(10)", js_string!("0.0000000600")), + TestAction::assert_eq("(0).toFixed(0)", js_string!("0")), + TestAction::assert_eq("(0).toFixed(1)", js_string!("0.0")), + TestAction::assert_eq("(0).toFixed(2)", js_string!("0.00")), + TestAction::assert_eq( + "(-1111111111111111111111).toFixed(8)", + js_string!("-1.1111111111111111e+21"), + ), + TestAction::assert_eq("(-0.1).toFixed(1)", js_string!("-0.1")), + TestAction::assert_eq("(-0.1).toFixed(2)", js_string!("-0.10")), + TestAction::assert_eq("(-0.1).toFixed(3)", js_string!("-0.100")), + TestAction::assert_eq("(-0.01).toFixed(2)", js_string!("-0.01")), + TestAction::assert_eq("(-0.01).toFixed(3)", js_string!("-0.010")), + TestAction::assert_eq("(-0.01).toFixed(4)", js_string!("-0.0100")), + TestAction::assert_eq("(-0.001).toFixed(2)", js_string!("-0.00")), + TestAction::assert_eq("(-0.001).toFixed(3)", js_string!("-0.001")), + TestAction::assert_eq("(-0.001).toFixed(4)", js_string!("-0.0010")), + TestAction::assert_eq("(-1).toFixed(4)", js_string!("-1.0000")), + TestAction::assert_eq("(-1).toFixed(1)", js_string!("-1.0")), + TestAction::assert_eq("(-1).toFixed(0)", js_string!("-1")), + TestAction::assert_eq("(-1.1).toFixed(0)", js_string!("-1")), + TestAction::assert_eq("(-12.1).toFixed(0)", js_string!("-12")), + TestAction::assert_eq("(-1.12).toFixed(0)", js_string!("-1")), + TestAction::assert_eq("(-12.12).toFixed(0)", js_string!("-12")), + TestAction::assert_eq("(-0.0000006).toFixed(7)", js_string!("-0.0000006")), + TestAction::assert_eq("(-0.00000006).toFixed(8)", js_string!("-0.00000006")), + TestAction::assert_eq("(-0.00000006).toFixed(9)", js_string!("-0.000000060")), + TestAction::assert_eq("(-0.00000006).toFixed(10)", js_string!("-0.0000000600")), + TestAction::assert_eq("(-0).toFixed(0)", js_string!("0")), + TestAction::assert_eq("(-0).toFixed(1)", js_string!("0.0")), + TestAction::assert_eq("(-0).toFixed(2)", js_string!("0.00")), + TestAction::assert_eq("(0.00001).toFixed(5)", js_string!("0.00001")), + TestAction::assert_eq( + "(0.0000000000000000001).toFixed(20)", + js_string!("0.00000000000000000010"), + ), + TestAction::assert_eq("(0.00001).toFixed(17)", js_string!("0.00001000000000000")), + TestAction::assert_eq("(1).toFixed(17)", js_string!("1.00000000000000000")), + TestAction::assert_eq( + "(100000000000000128).toFixed(1)", + js_string!("100000000000000128.0"), + ), + TestAction::assert_eq( + "(10000000000000128).toFixed(2)", + js_string!("10000000000000128.00"), + ), + TestAction::assert_eq( + "(10000000000000128).toFixed(20)", + js_string!("10000000000000128.00000000000000000000"), + ), + TestAction::assert_eq("(-42).toFixed(3)", js_string!("-42.000")), + TestAction::assert_eq( + "(-0.0000000000000000001).toFixed(20)", + js_string!("-0.00000000000000000010"), + ), + TestAction::assert_eq( + "(0.123123123123123).toFixed(20)", + js_string!("0.12312312312312299889"), + ), + TestAction::assert_eq( + "(-1000000000000000128).toFixed()", + js_string!("-1000000000000000128"), + ), + TestAction::assert_eq("(0).toFixed()", js_string!("0")), + TestAction::assert_eq( + "(1000000000000000128).toFixed()", + js_string!("1000000000000000128"), + ), + TestAction::assert_eq("(1000).toFixed()", js_string!("1000")), + TestAction::assert_eq("(0.00001).toFixed()", js_string!("0")), + // Test that we round up even when the last digit generated is even. + // dtoa does not do this in its original form. + TestAction::assert_eq("(0.5).toFixed(0)", js_string!("1")), + TestAction::assert_eq("(-0.5).toFixed(0)", js_string!("-1")), + TestAction::assert_eq("(1.25).toFixed(1)", js_string!("1.3")), + // This is bizare, but Spidermonkey and KJS behave the same. + TestAction::assert_eq("(234.2040).toFixed(4)", js_string!("234.2040")), + TestAction::assert_eq("(234.2040506).toFixed(4)", js_string!("234.2041")), + ]); +} + +// https://github.com/boa-dev/boa/issues/2609 +#[test] +fn issue_2609() { + run_test_actions([ + TestAction::assert_eq("(1.25).toFixed(1)", js_string!("1.3")), + TestAction::assert_eq("(1.35).toFixed(1)", js_string!("1.4")), ]); }