Skip to content

Commit e81fece

Browse files
Zaggy1024gmta
authored andcommitted
LibWeb: Abort media element resource selection upon loading a source
This fixes a crash when playing video on The Cutting Room Floor. Without aborting the resource selection algorithm, two resource selection algorithms could be running at once, resulting in the element requesting removal of a track from the PlaybackManager immediately after it had been replaced with a different instance. PlaybackManager asserts that removal of a track is valid, so this was causing a WebContent crash.
1 parent 122f97c commit e81fece

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

Libraries/LibWeb/HTML/HTMLMediaElement.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,11 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::load_element()
531531
{
532532
m_first_data_load_event_since_load_start = true;
533533

534-
// FIXME: 1. Abort any already-running instance of the resource selection algorithm for this element.
534+
// 1. Abort any already-running instance of the resource selection algorithm for this element.
535+
// NOTE: All deferred subroutines of the resource selection algorithm will be queued under the media element task
536+
// source, or run as part of the fetch. Step 2 will remove any subroutine from the queue. Step 6.2 will stop
537+
// any ongoing fetch operation. Therefore, all resource selection algorithms will be cancelled before a new
538+
// one begins.
535539

536540
// 2. Let pending tasks be a list of all tasks from the media element's media element event task source in one of the task queues.
537541
[[maybe_unused]] auto pending_tasks = HTML::main_thread_event_loop().task_queue().take_tasks_matching([&](auto& task) {
@@ -827,7 +831,7 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
827831
// 4. Await a stable state, allowing the task that invoked this algorithm to continue. The synchronous section consists of all the remaining
828832
// steps of this algorithm until the algorithm says the synchronous section has ended. (Steps in synchronous sections are marked with ⌛.)
829833

830-
queue_a_microtask(&document(), GC::create_function(realm.heap(), [this, &realm]() {
834+
queue_a_media_element_task([this, &realm]() {
831835
// FIXME: 5. ⌛ If the media element's blocked-on-parser flag is false, then populate the list of pending text tracks.
832836

833837
Optional<SelectMode> mode;
@@ -917,12 +921,12 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
917921

918922
// 5. If urlRecord was obtained successfully, run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one,
919923
// then the load failed.
920-
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [this, url_record = move(url_record), failed_with_attribute = move(failed_with_attribute)]() mutable {
924+
queue_a_media_element_task([this, url_record = move(url_record), failed_with_attribute = move(failed_with_attribute)]() mutable {
921925
if (url_record.has_value()) {
922926
fetch_resource(*url_record, move(failed_with_attribute)).release_value_but_fixme_should_propagate_errors();
923927
return;
924928
}
925-
}));
929+
});
926930

927931
// 8. Return. The element won't attempt to load another resource until this algorithm is triggered again.
928932
return;
@@ -957,7 +961,7 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
957961

958962
break;
959963
}
960-
}));
964+
});
961965

962966
return {};
963967
}

0 commit comments

Comments
 (0)