LibWeb: Remove "can run script" checks from MainThreadVM hooks

This allows Promises (including internal ones, like in Streams) and
FinalizationRegistry to work while scripting is disabled.

These were removed in the spec in support of WebDriver BiDi being able
to enable and disable scripting.

https://github.com/whatwg/html/commit/905b7218

This allows Fetch to work while scripting is disabled, due to its use
of Streams. This was noticeable if you disabled scripting in the UI,
or had a sandboxed iframe with scripting disabled.

There is more work to use job settings instead of realm inside these
hooks, but that's a separate issue.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/7409
Fixes https://github.com/LadybirdBrowser/ladybird/issues/3729
This commit is contained in:
Luke Wilde 2026-01-16 18:42:39 +00:00 committed by Shannon Booth
parent 3a6d82245b
commit 61a344a718
4 changed files with 29 additions and 16 deletions

View file

@ -254,20 +254,16 @@ void initialize_main_thread_vm(AgentType type)
// 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]].
auto& entry = *finalization_registry.cleanup_callback().callback().realm();
// 2. Check if we can run script with entry. If this returns "do not run", then return.
if (HTML::can_run_script(entry) == HTML::RunScriptDecision::DoNotRun)
return;
// 3. Prepare to run script with entry.
// 2. Prepare to run script with entry.
HTML::prepare_to_run_script(entry);
// 4. Let result be the result of performing CleanupFinalizationRegistry(finalizationRegistry).
// 3. Let result be the result of performing CleanupFinalizationRegistry(finalizationRegistry).
auto result = finalization_registry.cleanup();
// 5. Clean up after running script with entry.
// 4. Clean up after running script with entry.
HTML::clean_up_after_running_script(entry);
// 6. If result is an abrupt completion, then report the exception given by result.[[Value]].
// 5. If result is an abrupt completion, then report the exception given by result.[[Value]].
if (result.is_error())
HTML::report_exception(result, entry);
}));
@ -294,11 +290,7 @@ void initialize_main_thread_vm(AgentType type)
OwnPtr<JS::ExecutionContext> dummy_execution_context;
if (realm) {
// 1. If realm is not null, then check if we can run script with realm. If this returns "do not run" then return.
if (HTML::can_run_script(*realm) == HTML::RunScriptDecision::DoNotRun)
return;
// 2. If realm is not null, then prepare to run script with realm.
// 1. If realm is not null, then prepare to run script with realm.
HTML::prepare_to_run_script(*realm);
// IMPLEMENTATION DEFINED: Additionally to preparing to run a script, we also prepare to run a callback here. This matches WebIDL's
@ -318,10 +310,10 @@ void initialize_main_thread_vm(AgentType type)
vm.push_execution_context(*dummy_execution_context);
}
// 3. Let result be job().
// 2. Let result be job().
auto result = job->function()();
// 4. If realm is not null, then clean up after running script with job settings.
// 3. If realm is not null, then clean up after running script with job settings.
if (realm) {
// IMPLEMENTATION DEFINED: Disassociate the realm execution context from the script or module.
HTML::execution_context_of_realm(*realm).script_or_module = Empty {};
@ -335,7 +327,7 @@ void initialize_main_thread_vm(AgentType type)
vm.pop_execution_context();
}
// 5. If result is an abrupt completion, then report the exception given by result.[[Value]].
// 4. If result is an abrupt completion, then report the exception given by result.[[Value]].
if (result.is_error())
HTML::report_exception(result, *realm);
}));

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<style>
* {
margin: 0;
}
body {
background-color: white;
}
</style>
<img src="../images/can-load-images-in-sandboxed-iframe-with-no-scripting-ref.png">

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<head>
<link rel="match" href="../expected/can-load-images-in-sandboxed-iframe-with-no-scripting-ref.html" />
<style>
</style>
</head>
<body>
<iframe sandbox="allow-popups" width=100% height=644 style=border:none srcdoc="
<img src=&quot;../../Assets/120.png&quot;>
"></iframe>
</body>