mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
LibWeb: Abort dependent signals before firing abort event
Previously, there was a bug in the specification that would cause an assertion failure, due to the abort event being fired before all dependent signals were aborted.
This commit is contained in:
parent
68fcc37531
commit
3ae4ea7b10
Notes:
github-actions[bot]
2024-09-09 13:12:26 +00:00
Author: https://github.com/tcl3
Commit: 3ae4ea7b10
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1336
3 changed files with 46 additions and 13 deletions
1
Tests/LibWeb/Text/expected/DOM/AbortSignal-any-crash.txt
Normal file
1
Tests/LibWeb/Text/expected/DOM/AbortSignal-any-crash.txt
Normal file
|
@ -0,0 +1 @@
|
|||
PASS (didn't crash)
|
11
Tests/LibWeb/Text/input/DOM/AbortSignal-any-crash.html
Normal file
11
Tests/LibWeb/Text/input/DOM/AbortSignal-any-crash.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const abortController = new AbortController();
|
||||
const signal = AbortSignal.any([abortController.signal]);
|
||||
abortController.signal.addEventListener("abort", () => { AbortSignal.any([signal]) });
|
||||
abortController.abort();
|
||||
println("PASS (didn't crash)");
|
||||
});
|
||||
</script>
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
||||
* Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
|
||||
* Copyright (c) 2024, Tim Ledbetter <tim.ledbetter@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -58,21 +58,42 @@ void AbortSignal::signal_abort(JS::Value reason)
|
|||
else
|
||||
m_abort_reason = WebIDL::AbortError::create(realm(), "Aborted without reason"_fly_string).ptr();
|
||||
|
||||
// 3. For each algorithm in signal’s abort algorithms: run algorithm.
|
||||
for (auto& algorithm : m_abort_algorithms)
|
||||
algorithm->function()();
|
||||
// 3. Let dependentSignalsToAbort be a new list.
|
||||
Vector<JS::Handle<AbortSignal>> dependent_signals_to_abort;
|
||||
|
||||
// 4. Empty signal’s abort algorithms.
|
||||
m_abort_algorithms.clear();
|
||||
// 4. For each dependentSignal of signal’s dependent signals:
|
||||
for (auto const& dependent_signal : m_dependent_signals) {
|
||||
// 1. If dependentSignal is not aborted, then:
|
||||
if (!dependent_signal->aborted()) {
|
||||
// 1. Set dependentSignal’s abort reason to signal’s abort reason.
|
||||
dependent_signal->set_reason(m_abort_reason);
|
||||
|
||||
// 5. Fire an event named abort at signal.
|
||||
auto abort_event = Event::create(realm(), HTML::EventNames::abort);
|
||||
abort_event->set_is_trusted(true);
|
||||
dispatch_event(abort_event);
|
||||
// 2. Append dependentSignal to dependentSignalsToAbort.
|
||||
dependent_signals_to_abort.append(*dependent_signal);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. For each dependentSignal of signal’s dependent signals, signal abort on dependentSignal with signal’s abort reason.
|
||||
for (auto const& dependent_signal : m_dependent_signals)
|
||||
dependent_signal->signal_abort(reason);
|
||||
// https://dom.spec.whatwg.org/#run-the-abort-steps
|
||||
auto run_the_abort_steps = [](auto& signal) {
|
||||
// 1. For each algorithm in signal’s abort algorithms: run algorithm.
|
||||
for (auto& algorithm : signal.m_abort_algorithms)
|
||||
algorithm->function()();
|
||||
|
||||
// 2. Empty signal’s abort algorithms.
|
||||
signal.m_abort_algorithms.clear();
|
||||
|
||||
// 3. Fire an event named abort at signal.
|
||||
auto abort_event = Event::create(signal.realm(), HTML::EventNames::abort);
|
||||
abort_event->set_is_trusted(true);
|
||||
signal.dispatch_event(abort_event);
|
||||
};
|
||||
|
||||
// 5. Run the abort steps for signal.
|
||||
run_the_abort_steps(*this);
|
||||
|
||||
// 6. For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
|
||||
for (auto const& dependent_signal : dependent_signals_to_abort)
|
||||
run_the_abort_steps(*dependent_signal);
|
||||
}
|
||||
|
||||
void AbortSignal::set_onabort(WebIDL::CallbackType* event_handler)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue