mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-19 02:10:26 +00:00
LibWeb: Address edge case on async module load
Issue #6294 describes an edge case where the browser crash if the same module is loaded three times in a document, but all attempts fail. Failure scenario: 1. Module load 1 set the state to "Fetching" 2. Module load 2 registers a callback to `on_complete` since the current state is "Fetching" 3. Module load 1 finish with a failure, invoking the callback for load number 2 4. Module load 3 cause a crash. The state is neither "Fetching" or "ModuleScript", so we'll reset the state to "Fetching". This invokes the callback for module load 2 again, now with an unexpected state which will cause an assert violation. Proposed fix is to remove the condition that invokes `on_complete` immediately for successfully loaded modules only, the callback should be invoked regardless of whether the fetch succeeded or failed. This reveals a separate bug in HTMLScriptElement, where `mark_as_ready()` can be invoked before `m_steps_to_run_when_the_result_is_ready` is assigned. This appears to be a spec bug, reported as https://github.com/whatwg/html/issues/12073 and addressed by delaying the callback by a task, similar to the issue was resolved for inline scripts.
This commit is contained in:
parent
1106496d1c
commit
14ccc87190
Notes:
github-actions[bot]
2026-01-13 17:13:50 +00:00
Author: https://github.com/crhaglun 🔰
Commit: 14ccc87190
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7326
Reviewed-by: https://github.com/gmta
Reviewed-by: https://github.com/shannonbooth ✅
5 changed files with 32 additions and 3 deletions
|
|
@ -478,6 +478,19 @@ void HTMLScriptElement::prepare_script()
|
|||
if (!has_attribute(HTML::AttributeNames::integrity))
|
||||
options.integrity_metadata = resolve_a_module_integrity_metadata(*url, settings_object);
|
||||
|
||||
// AD-HOC: Queue an element task on the networking task source to run the onComplete steps
|
||||
// This resolves an edge case where mark_as_ready() can execute before we set
|
||||
// m_steps_to_run_when_the_result_is_ready
|
||||
// See https://github.com/whatwg/html/issues/12073
|
||||
auto on_complete = create_on_fetch_script_complete(heap(), [this](auto result) {
|
||||
queue_an_element_task(Task::Source::Networking, [this, result = move(result)] {
|
||||
if (!result)
|
||||
mark_as_ready(ResultState::Null {});
|
||||
else
|
||||
mark_as_ready(Result(*result));
|
||||
});
|
||||
});
|
||||
|
||||
// Fetch an external module script graph given url, settings object, options, and onComplete.
|
||||
fetch_external_module_script_graph(realm(), *url, settings_object, options, on_complete);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue