fix(js): console.log(Error) must not trigger Error.prepareStackTrace

deviceandbrowserinfo.com detects CDP by setting Error.prepareStackTrace as a spy, then calling console.log(new Error()). _consoleFn accessed a.stack, which fires prepareStackTrace if set. Fix: save/clear/restore around the .stack access.
This commit is contained in:
SGavrl authored and GitHub committed 2026-06-10 20:48:45 +00:00
1 parent 534de77882
commit 3c92c36862
2 files changed
+22 -1

No files matched your search

+7 -1
View File
@@ -212,7 +212,13 @@ const _consoleFn = (level, args) => {
try { Deno.core.ops.op_console_msg(level, args.map(a => {
if (a === null) return "null";
if (a === undefined) return "undefined";
if (a instanceof Error) return a.stack || a.message || String(a);
if (a instanceof Error) {
const _pst = Error.prepareStackTrace;
if (_pst !== undefined) Error.prepareStackTrace = undefined;
const _s = a.stack || a.message || String(a);
if (_pst !== undefined) Error.prepareStackTrace = _pst;
return _s;
}
if (typeof a === "object") {
try {
const s = JSON.stringify(a);
+15
View File
@@ -2452,6 +2452,21 @@ mod tests {
);
}
#[test]
fn console_log_error_does_not_trigger_prepare_stack_trace() {
let mut rt = setup_runtime("<div></div>");
let result = rt.evaluate(r#"
let called = false;
const saved = Error.prepareStackTrace;
Error.prepareStackTrace = function() { called = true; return saved; };
const e = new Error("test");
console.log(e);
Error.prepareStackTrace = saved;
return called;
"#).unwrap();
assert_eq!(result, serde_json::json!(false));
}
#[test]
fn element_aria_reflection_setters_write_through() {
let mut rt = setup_runtime(r#"<div id="d"></div>"#);