make report_pending_exception safe and adjust callers (#35351)

Signed-off-by: Nolen Scaife <nolen@scaife.org>
This commit is contained in:
Nolen Scaife 2025-02-08 15:22:44 -07:00 committed by GitHub
parent 827012fc08
commit df73d02932
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 42 additions and 44 deletions

View file

@ -278,12 +278,12 @@ impl Drop for CallSetup {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
LeaveRealm(*self.cx, self.old_realm); LeaveRealm(*self.cx, self.old_realm);
if self.handling == ExceptionHandling::Report {
let ar = enter_realm(&*self.exception_global);
report_pending_exception(*self.cx, true, InRealm::Entered(&ar), CanGc::note());
}
drop(self.incumbent_script.take());
drop(self.entry_script.take().unwrap());
} }
if self.handling == ExceptionHandling::Report {
let ar = enter_realm(&*self.exception_global);
report_pending_exception(self.cx, true, InRealm::Entered(&ar), CanGc::note());
}
drop(self.incumbent_script.take());
drop(self.entry_script.take().unwrap());
} }
} }

View file

@ -271,31 +271,35 @@ impl ErrorInfo {
/// ///
/// The `dispatch_event` argument is temporary and non-standard; passing false /// The `dispatch_event` argument is temporary and non-standard; passing false
/// prevents dispatching the `error` event. /// prevents dispatching the `error` event.
pub(crate) unsafe fn report_pending_exception( pub(crate) fn report_pending_exception(
cx: *mut JSContext, cx: SafeJSContext,
dispatch_event: bool, dispatch_event: bool,
realm: InRealm, realm: InRealm,
can_gc: CanGc, can_gc: CanGc,
) { ) {
let cx = SafeJSContext::from_ptr(cx); unsafe {
if !JS_IsExceptionPending(*cx) { if !JS_IsExceptionPending(*cx) {
return; return;
}
} }
rooted!(in(*cx) let mut value = UndefinedValue()); rooted!(in(*cx) let mut value = UndefinedValue());
if !JS_GetPendingException(*cx, value.handle_mut()) {
JS_ClearPendingException(*cx);
error!("Uncaught exception: JS_GetPendingException failed");
return;
}
JS_ClearPendingException(*cx); unsafe {
if !JS_GetPendingException(*cx, value.handle_mut()) {
JS_ClearPendingException(*cx);
error!("Uncaught exception: JS_GetPendingException failed");
return;
}
JS_ClearPendingException(*cx);
}
let error_info = ErrorInfo::from_value(value.handle(), cx); let error_info = ErrorInfo::from_value(value.handle(), cx);
error!( error!(
"Error at {}:{}:{} {}", "Error at {}:{}:{} {}",
error_info.filename, error_info.lineno, error_info.column, error_info.message error_info.filename, error_info.lineno, error_info.column, error_info.message
); );
#[cfg(feature = "js_backtrace")] #[cfg(feature = "js_backtrace")]
{ {
LAST_EXCEPTION_BACKTRACE.with(|backtrace| { LAST_EXCEPTION_BACKTRACE.with(|backtrace| {

View file

@ -187,11 +187,10 @@ fn create_html_element(
// Substep 1. Report exception for definitions constructors corresponding // Substep 1. Report exception for definitions constructors corresponding
// JavaScript objects associated realms global object. // JavaScript objects associated realms global object.
unsafe {
let ar = enter_realm(&*global); let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error); throw_dom_exception(cx, &global, error);
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
}
// Substep 2. Set result to a new element that implements the HTMLUnknownElement interface, // Substep 2. Set result to a new element that implements the HTMLUnknownElement interface,
// with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix, // with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix,

View file

@ -786,7 +786,6 @@ impl CustomElementDefinition {
} }
/// <https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element> /// <https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element>
#[allow(unsafe_code)]
pub(crate) fn upgrade_element( pub(crate) fn upgrade_element(
definition: Rc<CustomElementDefinition>, definition: Rc<CustomElementDefinition>,
element: &Element, element: &Element,
@ -848,11 +847,9 @@ pub(crate) fn upgrade_element(
// Step 8.exception.3 // Step 8.exception.3
let global = GlobalScope::current().expect("No current global"); let global = GlobalScope::current().expect("No current global");
let cx = GlobalScope::get_cx(); let cx = GlobalScope::get_cx();
unsafe { let ar = enter_realm(&*global);
let ar = enter_realm(&*global); throw_dom_exception(cx, &global, error);
throw_dom_exception(cx, &global, error); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
}
return; return;
} }

View file

@ -582,11 +582,9 @@ impl EventTarget {
}); });
if handler.get().is_null() { if handler.get().is_null() {
// Step 3.7 // Step 3.7
unsafe { let ar = enter_realm(self);
let ar = enter_realm(self); // FIXME(#13152): dispatch error event.
// FIXME(#13152): dispatch error event. report_pending_exception(cx, false, InRealm::Entered(&ar), can_gc);
report_pending_exception(*cx, false, InRealm::Entered(&ar), can_gc);
}
return None; return None;
} }

View file

@ -2549,7 +2549,7 @@ impl GlobalScope {
if compiled_script.is_null() { if compiled_script.is_null() {
debug!("error compiling Dom string"); debug!("error compiling Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
return false; return false;
} }
}, },
@ -2598,7 +2598,7 @@ impl GlobalScope {
if !result { if !result {
debug!("error evaluating Dom string"); debug!("error evaluating Dom string");
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
} }
maybe_resume_unwind(); maybe_resume_unwind();

View file

@ -499,7 +499,12 @@ impl WorkerGlobalScope {
println!("evaluate_script failed"); println!("evaluate_script failed");
unsafe { unsafe {
let ar = enter_realm(self); let ar = enter_realm(self);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(
JSContext::from_ptr(cx),
true,
InRealm::Entered(&ar),
can_gc,
);
} }
} }
}, },

View file

@ -593,20 +593,15 @@ impl ModuleTree {
let module_error = self.rethrow_error.borrow(); let module_error = self.rethrow_error.borrow();
if let Some(exception) = &*module_error { if let Some(exception) = &*module_error {
let ar = enter_realm(global);
unsafe { unsafe {
let ar = enter_realm(global);
JS_SetPendingException( JS_SetPendingException(
*GlobalScope::get_cx(), *GlobalScope::get_cx(),
exception.handle(), exception.handle(),
ExceptionStackBehavior::Capture, ExceptionStackBehavior::Capture,
); );
report_pending_exception(
*GlobalScope::get_cx(),
true,
InRealm::Entered(&ar),
can_gc,
);
} }
report_pending_exception(GlobalScope::get_cx(), true, InRealm::Entered(&ar), can_gc);
} }
} }