Fix crash when closing window containing video element (#31413)

* Forbid casting DOM objects when JS runtime is shutting down.

* Remove media controls from document when element is removed from the tree.
This commit is contained in:
Josh Matthews 2024-02-23 07:18:49 -05:00 committed by GitHub
parent e078a99817
commit b182bdfa52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 2 deletions

View file

@ -9,6 +9,7 @@ use std::mem;
pub use crate::dom::bindings::codegen::InheritTypes::*; pub use crate::dom::bindings::codegen::InheritTypes::*;
use crate::dom::bindings::conversions::{get_dom_class, DerivedFrom, IDLInterface}; use crate::dom::bindings::conversions::{get_dom_class, DerivedFrom, IDLInterface};
use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::DomObject;
use crate::script_runtime::runtime_is_alive;
/// A trait to hold the cast functions of IDL interfaces that either derive /// A trait to hold the cast functions of IDL interfaces that either derive
/// or are derived from other interfaces. /// or are derived from other interfaces.
@ -18,6 +19,14 @@ pub trait Castable: IDLInterface + DomObject + Sized {
where where
T: DerivedFrom<Self>, T: DerivedFrom<Self>,
{ {
// This is a weird place for this check to live, but it should catch any
// attempts to interact with DOM objects from Drop implementations that run
// as a result of the runtime shutting down and finalizing all remaining objects.
debug_assert!(
runtime_is_alive(),
"Attempting to interact with DOM objects after JS runtime has shut down."
);
let class = unsafe { get_dom_class(self.reflector().get_jsobject().get()).unwrap() }; let class = unsafe { get_dom_class(self.reflector().get_jsobject().get()).unwrap() };
T::derives(class) T::derives(class)
} }

View file

@ -1998,8 +1998,6 @@ impl Drop for HTMLMediaElement {
warn!("GLPlayer disappeared!: {:?}", err); warn!("GLPlayer disappeared!: {:?}", err);
} }
} }
self.remove_controls();
} }
} }
@ -2454,6 +2452,8 @@ impl VirtualMethods for HTMLMediaElement {
fn unbind_from_tree(&self, context: &UnbindContext) { fn unbind_from_tree(&self, context: &UnbindContext) {
self.super_type().unwrap().unbind_from_tree(context); self.super_type().unwrap().unbind_from_tree(context);
self.remove_controls();
if context.tree_connected { if context.tree_connected {
let task = MediaElementMicrotask::PauseIfNotInDocumentTask { let task = MediaElementMicrotask::PauseIfNotInDocumentTask {
elem: DomRoot::from_ref(self), elem: DomRoot::from_ref(self),

View file

@ -812,6 +812,10 @@ thread_local!(
static THREAD_ACTIVE: Cell<bool> = Cell::new(true); static THREAD_ACTIVE: Cell<bool> = Cell::new(true);
); );
pub(crate) fn runtime_is_alive() -> bool {
THREAD_ACTIVE.with(|t| t.get())
}
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe extern "C" fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void) { unsafe extern "C" fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_void) {
if !THREAD_ACTIVE.with(|t| t.get()) { if !THREAD_ACTIVE.with(|t| t.get()) {