LibWeb: Ensure requests modules is not empty before indexing into it
Regression from 5af613aa65
Fixes: #2676
This commit is contained in:
parent
2ff03ea7d2
commit
30c8510725
Notes:
github-actions[bot]
2024-12-01 14:50:09 +00:00
Author: https://github.com/shannonbooth Commit: https://github.com/LadybirdBrowser/ladybird/commit/30c85107256 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2677 Reviewed-by: https://github.com/awesomekling
4 changed files with 64 additions and 47 deletions
|
@ -471,16 +471,35 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
|
|||
}
|
||||
|
||||
// 7. If referrer is a Cyclic Module Record and moduleRequest is equal to the first element of referrer.[[RequestedModules]], then:
|
||||
if (referrer.has<GC::Ref<JS::CyclicModule>>() && module_request == referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules().first()) {
|
||||
// 1. For each ModuleRequest record requested of referrer.[[RequestedModules]]:
|
||||
for (auto const& module_request : referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules()) {
|
||||
// 1. If moduleRequest.[[Attributes]] contains a Record entry such that entry.[[Key]] is not "type", then:
|
||||
for (auto const& attribute : module_request.attributes) {
|
||||
if (attribute.key == "type"sv)
|
||||
continue;
|
||||
if (referrer.has<GC::Ref<JS::CyclicModule>>()) {
|
||||
// FIXME: Why do we need to check requested modules is empty here?
|
||||
if (auto const& requested_modules = referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules(); !requested_modules.is_empty() && module_request == requested_modules.first()) {
|
||||
// 1. For each ModuleRequest record requested of referrer.[[RequestedModules]]:
|
||||
for (auto const& module_request : referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules()) {
|
||||
// 1. If moduleRequest.[[Attributes]] contains a Record entry such that entry.[[Key]] is not "type", then:
|
||||
for (auto const& attribute : module_request.attributes) {
|
||||
if (attribute.key == "type"sv)
|
||||
continue;
|
||||
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: a new SyntaxError exception, [[Target]]: empty }.
|
||||
auto completion = JS::throw_completion(JS::SyntaxError::create(*module_map_realm, "Module request attributes must only contain a type attribute"_string));
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: a new SyntaxError exception, [[Target]]: empty }.
|
||||
auto completion = JS::throw_completion(JS::SyntaxError::create(*module_map_realm, "Module request attributes must only contain a type attribute"_string));
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 3. Return.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Resolve a module specifier given referencingScript and moduleRequest.[[Specifier]], catching any
|
||||
// exceptions. If they throw an exception, let resolutionError be the thrown exception.
|
||||
auto maybe_exception = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier);
|
||||
|
||||
// 3. If the previous step threw an exception, then:
|
||||
if (maybe_exception.is_exception()) {
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: resolutionError, [[Target]]: empty }.
|
||||
auto completion = dom_exception_to_throw_completion(main_thread_vm(), maybe_exception.exception());
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
@ -488,45 +507,29 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
|
|||
// 3. Return.
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Let moduleType be the result of running the module type from module request steps given moduleRequest.
|
||||
auto module_type = HTML::module_type_from_module_request(module_request);
|
||||
|
||||
// 5. If the result of running the module type allowed steps given moduleType and moduleMapRealm is false, then:
|
||||
if (!HTML::module_type_allowed(*module_map_realm, module_type)) {
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: a new TypeError exception, [[Target]]: empty }.
|
||||
auto completion = JS::throw_completion(JS::SyntaxError::create(*module_map_realm, MUST(String::formatted("Module type '{}' is not supported", module_type))));
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 3. Return
|
||||
return;
|
||||
}
|
||||
|
||||
// Spec-Note: This step is essentially validating all of the requested module specifiers and type attributes
|
||||
// when the first call to HostLoadImportedModule for a static module dependency list is made, to
|
||||
// avoid further loading operations in the case any one of the dependencies has a static error.
|
||||
// We treat a module with unresolvable module specifiers or unsupported type attributes the same
|
||||
// as one that cannot be parsed; in both cases, a syntactic issue makes it impossible to ever
|
||||
// contemplate linking the module later.
|
||||
}
|
||||
|
||||
// 2. Resolve a module specifier given referencingScript and moduleRequest.[[Specifier]], catching any
|
||||
// exceptions. If they throw an exception, let resolutionError be the thrown exception.
|
||||
auto maybe_exception = HTML::resolve_module_specifier(referencing_script, module_request.module_specifier);
|
||||
|
||||
// 3. If the previous step threw an exception, then:
|
||||
if (maybe_exception.is_exception()) {
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: resolutionError, [[Target]]: empty }.
|
||||
auto completion = dom_exception_to_throw_completion(main_thread_vm(), maybe_exception.exception());
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 3. Return.
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Let moduleType be the result of running the module type from module request steps given moduleRequest.
|
||||
auto module_type = HTML::module_type_from_module_request(module_request);
|
||||
|
||||
// 5. If the result of running the module type allowed steps given moduleType and moduleMapRealm is false, then:
|
||||
if (!HTML::module_type_allowed(*module_map_realm, module_type)) {
|
||||
// 1. Let completion be Completion Record { [[Type]]: throw, [[Value]]: a new TypeError exception, [[Target]]: empty }.
|
||||
auto completion = JS::throw_completion(JS::SyntaxError::create(*module_map_realm, MUST(String::formatted("Module type '{}' is not supported", module_type))));
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 3. Return
|
||||
return;
|
||||
}
|
||||
|
||||
// Spec-Note: This step is essentially validating all of the requested module specifiers and type attributes
|
||||
// when the first call to HostLoadImportedModule for a static module dependency list is made, to
|
||||
// avoid further loading operations in the case any one of the dependencies has a static error.
|
||||
// We treat a module with unresolvable module specifiers or unsupported type attributes the same
|
||||
// as one that cannot be parsed; in both cases, a syntactic issue makes it impossible to ever
|
||||
// contemplate linking the module later.
|
||||
}
|
||||
|
||||
// 8. Disallow further import maps given moduleMapRealm.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
PASS! (Didn't crash)
|
|
@ -0,0 +1,5 @@
|
|||
// NOTE: Doesn't matter what this imports, but this imports itself so there is no import error in test logs.
|
||||
import("./import-in-a-module.js");
|
||||
|
||||
const returnValue = "PASS! (Didn't crash)";
|
||||
export default returnValue;
|
|
@ -0,0 +1,8 @@
|
|||
<script src="../../include.js"></script>
|
||||
<script type="module">
|
||||
import m from "./import-in-a-module.js";
|
||||
|
||||
test(() => {
|
||||
println(m);
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue