From 036bca69ae90a84a414e9543c51e29c3bbe1dfac Mon Sep 17 00:00:00 2001 From: Smitty Date: Tue, 6 Feb 2024 04:01:47 -0500 Subject: [PATCH] Fix crash on large console log (#31267) --- components/script/dom/console.rs | 20 ++++++++--- .../console-log-large-array.any.js.ini | 6 ++++ tests/wpt/meta/MANIFEST.json | 36 +++++++++++++++++++ .../console-log-large-array.any.js.ini | 6 ++++ .../console/console-log-large-array.any.js | 8 +++++ 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 tests/wpt/meta-legacy-layout/console/console-log-large-array.any.js.ini create mode 100644 tests/wpt/meta/console/console-log-large-array.any.js.ini create mode 100644 tests/wpt/tests/console/console-log-large-array.any.js diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 9589769ab88..f8547c449ff 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -23,6 +23,8 @@ use crate::script_runtime::JSContext; /// The maximum object depth logged by console methods. const MAX_LOG_DEPTH: usize = 10; +/// The maximum elements in an object logged by console methods. +const MAX_LOG_CHILDREN: usize = 15; // https://developer.mozilla.org/en-US/docs/Web/API/Console pub struct Console(()); @@ -91,10 +93,6 @@ fn stringify_handle_value(message: HandleValue) -> DOMString { if !GetBuiltinClass(cx, obj.handle().into(), &mut object_class as *mut _) { return DOMString::from("/* invalid */"); } - if object_class != ESClass::Array && object_class != ESClass::Object { - return handle_value_to_string(cx, value); - } - let mut ids = IdVector::new(cx); if !GetPropertyKeys( cx, @@ -104,9 +102,18 @@ fn stringify_handle_value(message: HandleValue) -> DOMString { ) { return DOMString::from("/* invalid */"); } + let truncate = ids.len() > MAX_LOG_CHILDREN; + if object_class != ESClass::Array && object_class != ESClass::Object { + if truncate { + return DOMString::from("…"); + } else { + return handle_value_to_string(cx, value); + } + } + let mut explicit_keys = object_class == ESClass::Object; let mut props = Vec::with_capacity(ids.len()); - for id in &*ids { + for id in ids.iter().take(MAX_LOG_CHILDREN) { rooted!(in(cx) let id = *id); rooted!(in(cx) let mut desc = PropertyDescriptor::default()); @@ -154,6 +161,9 @@ fn stringify_handle_value(message: HandleValue) -> DOMString { props.push(value_string.to_string()); } } + if truncate { + props.push("…".to_string()); + } if object_class == ESClass::Array { DOMString::from(format!("[{}]", itertools::join(props, ", "))) } else { diff --git a/tests/wpt/meta-legacy-layout/console/console-log-large-array.any.js.ini b/tests/wpt/meta-legacy-layout/console/console-log-large-array.any.js.ini new file mode 100644 index 00000000000..10c5af82ff9 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/console/console-log-large-array.any.js.ini @@ -0,0 +1,6 @@ +[console-log-large-array.any.html] + +[console-log-large-array.any.worker.html] + +[console-log-large-array.any.shadowrealm.html] + expected: ERROR diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 547ea0d9709..959872cb954 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -517775,6 +517775,42 @@ {} ] ], + "console-log-large-array.any.js": [ + "e5cb92d9d36d4ae43416be7ccba2551249d43a88", + [ + "console/console-log-large-array.any.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,shadowrealm" + ] + ] + } + ], + [ + "console/console-log-large-array.any.shadowrealm.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,shadowrealm" + ] + ] + } + ], + [ + "console/console-log-large-array.any.worker.html", + { + "script_metadata": [ + [ + "global", + "window,dedicatedworker,shadowrealm" + ] + ] + } + ] + ], "console-log-symbol.any.js": [ "a2facb6c64e86428383260735ed2df3e88c2c809", [ diff --git a/tests/wpt/meta/console/console-log-large-array.any.js.ini b/tests/wpt/meta/console/console-log-large-array.any.js.ini new file mode 100644 index 00000000000..75ce6bebf1f --- /dev/null +++ b/tests/wpt/meta/console/console-log-large-array.any.js.ini @@ -0,0 +1,6 @@ +[console-log-large-array.any.worker.html] + +[console-log-large-array.any.shadowrealm.html] + expected: ERROR + +[console-log-large-array.any.html] diff --git a/tests/wpt/tests/console/console-log-large-array.any.js b/tests/wpt/tests/console/console-log-large-array.any.js new file mode 100644 index 00000000000..e5cb92d9d36 --- /dev/null +++ b/tests/wpt/tests/console/console-log-large-array.any.js @@ -0,0 +1,8 @@ +// META: global=window,dedicatedworker,shadowrealm +"use strict"; +// https://console.spec.whatwg.org/ + +test(() => { + console.log(new Array(10000000).fill("x")); + console.log(new Uint8Array(10000000)); +}, "Logging large arrays works");