mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 17:55:07 +02: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:
committed by
Shannon Booth
parent
1106496d1c
commit
14ccc87190
Notes:
github-actions[bot]
2026-01-13 17:13:50 +00:00
Author: https://github.com/crhaglun 🔰 Commit: https://github.com/LadybirdBrowser/ladybird/commit/14ccc871908 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7326 Reviewed-by: https://github.com/gmta Reviewed-by: https://github.com/shannonbooth ✅
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Adapted from https://github.com/LadybirdBrowser/ladybird/issues/6294
|
||||
Regression test for a crash when target JS modules fail to load
|
||||
-->
|
||||
<script src="../../include.js"></script>
|
||||
|
||||
<script defer="defer" async type="module" src="file///doesnotexist1.file"></script>
|
||||
<script defer="defer" async type="module" src="file///doesnotexist1.file"></script>
|
||||
|
||||
<script src="file///doesnotexist1.file"></script>
|
||||
|
||||
<script defer="defer" async type="module" src="file///doesnotexist1.file"></script>
|
||||
|
||||
<script defer="defer">
|
||||
test(() => println("PASS! (Didn't crash)"));
|
||||
</script>
|
||||
Reference in New Issue
Block a user