You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chunk-js: URL.parse reentrancy and stack call-site caching can abort the process #300
Follow-up to #297. Review of the structuredClone fix found two more places where application JavaScript can make native code panic inside a V8 callback, which aborts the whole process hosting core. Both reproduce as SIGABRT in chunk-js, and both live in upstream crates.
URL.parse reentrancy (deno_web 0.289.0, url.rs:39). A subclass whose constructor builds a second URL consumes the serialization URL.parse is waiting to retrieve, and the op panics because UrlSerialization is missing. A setter on URL's brand symbol triggers the same failure.
Call-site cache poisoning (deno_core 0.411.0, error.rs:1837, 1847, 1857 and 2055). With Error.prepareStackTrace returning raw frames, an inherited Array.prototype index setter poisons the internal call-site cache. getFileName, getLineNumber, getColumnNumber and toString then unwrap or cast values unchecked.
Options
Patch the unchecked sites, either upstream or as a small [patch.crates-io] fork, so they throw instead of panic.
Or avoid the paths in chunk-js: drop URL.parse and make the URL constructor non-reentrant, and stop exposing raw call sites by not honouring Error.prepareStackTrace.
Also check the other deno_core and deno_web callbacks that application code can reach for the same class of bug.
Status after #341, which closes both paths reported here and a third found while auditing (a failed dynamic import() whose rejection had a non-string message).
Still open:
Abort through errorAdditionalPropertyKeys.deno_core (error.rs near 1274) sizes a Vec from an application-supplied array while converting a thrown error. throw Object.assign(new Error("x"), { [Symbol.for("errorAdditionalPropertyKeys")]: new Array(4294967295) }) aborts from an invocation, a top-level throw, a microtask error or an unhandled rejection. Review of fix(js): stop application JavaScript from aborting core through URL.parse, stack traces and import() #341 showed an in-crate fix is feasible: install the report-exception and unhandled-rejection hooks before bootstrap removes Deno, own the raw V8 exception and promise boundaries for invocation and module evaluation, and convert with a bounded conversion (JsError::from_v8_message worked in a probe) instead of from_v8_exception. The existing .map_err(js_error) calls are too late. The dependency's fallback paths need covering too.
Deadline escape during error conversion (a hang, not an abort). deno_core (error.rs near 1666) cancels termination before converting the exception, so an error whose message getter never returns outlives the deadline. Owning the conversion as above would likely close this as well.
Activity
oglassdev commentedon Oct 12, 2026
Status after #341, which closes both paths reported here and a third found while auditing (a failed dynamic
import()whose rejection had a non-stringmessage).Still open:
errorAdditionalPropertyKeys.deno_core(error.rsnear 1274) sizes aVecfrom an application-supplied array while converting a thrown error.throw Object.assign(new Error("x"), { [Symbol.for("errorAdditionalPropertyKeys")]: new Array(4294967295) })aborts from an invocation, a top-level throw, a microtask error or an unhandled rejection. Review of fix(js): stop application JavaScript from aborting core through URL.parse, stack traces and import() #341 showed an in-crate fix is feasible: install the report-exception and unhandled-rejection hooks before bootstrap removesDeno, own the raw V8 exception and promise boundaries for invocation and module evaluation, and convert with a bounded conversion (JsError::from_v8_messageworked in a probe) instead offrom_v8_exception. The existing.map_err(js_error)calls are too late. The dependency's fallback paths need covering too.deno_core(error.rsnear 1666) cancels termination before converting the exception, so an error whosemessagegetter never returns outlives the deadline. Owning the conversion as above would likely close this as well.🤖 Generated with Claude Code
fix(js): close URL.parse, call-site and dynamic import abort paths
fix(js): stop application JavaScript from aborting core through URL.p…