1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:17:45 +00:00

LibJS: Propagate out-of-memory errors from HostImportModuleDynamically

This commit is contained in:
Timothy Flynn 2023-02-17 07:30:42 -05:00 committed by Tim Flynn
parent f98d0acd27
commit f6503577f6
4 changed files with 12 additions and 9 deletions

View file

@ -3589,7 +3589,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
ModuleRequest request { specifier_string, assertions };
// 12. Perform HostImportModuleDynamically(referencingScriptOrModule, moduleRequest, promiseCapability).
interpreter.vm().host_import_module_dynamically(referencing_script_or_module, move(request), promise_capability);
MUST_OR_THROW_OOM(interpreter.vm().host_import_module_dynamically(referencing_script_or_module, move(request), promise_capability));
// 13. Return promiseCapability.[[Promise]].
return Value { promise_capability->promise() };

View file

@ -222,7 +222,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, DeprecatedString spec
TRY(vm.push_execution_context(eval_context, {}));
// 6. Perform HostImportModuleDynamically(null, specifierString, innerCapability).
vm.host_import_module_dynamically(Empty {}, ModuleRequest { move(specifier_string) }, inner_capability);
MUST_OR_THROW_OOM(vm.host_import_module_dynamically(Empty {}, ModuleRequest { move(specifier_string) }, inner_capability));
// 7. Suspend evalContext and remove it from the execution context stack.
// NOTE: We don't support this concept yet.

View file

@ -81,7 +81,7 @@ VM::VM(OwnPtr<CustomData> custom_data)
return resolve_imported_module(move(referencing_script_or_module), specifier);
};
host_import_module_dynamically = [&](ScriptOrModule, ModuleRequest const&, PromiseCapability const& promise_capability) {
host_import_module_dynamically = [&](ScriptOrModule, ModuleRequest const&, PromiseCapability const& promise_capability) -> ThrowCompletionOr<void> {
// By default, we throw on dynamic imports this is to prevent arbitrary file access by scripts.
VERIFY(current_realm());
auto& realm = *current_realm();
@ -90,7 +90,7 @@ VM::VM(OwnPtr<CustomData> custom_data)
// If you are here because you want to enable dynamic module importing make sure it won't be a security problem
// by checking the default implementation of HostImportModuleDynamically and creating your own hook or calling
// vm.enable_default_host_import_module_dynamically_hook().
promise->reject(Error::create(realm, ErrorType::DynamicImportNotAllowed.message()).release_allocated_value_but_fixme_should_propagate_errors());
promise->reject(MUST_OR_THROW_OOM(Error::create(realm, ErrorType::DynamicImportNotAllowed.message())));
promise->perform_then(
NativeFunction::create(realm, "", [](auto&) -> ThrowCompletionOr<Value> {
@ -106,6 +106,8 @@ VM::VM(OwnPtr<CustomData> custom_data)
return js_undefined();
}),
{});
return {};
};
host_finish_dynamic_import = [&](ScriptOrModule referencing_script_or_module, ModuleRequest const& specifier, PromiseCapability const& promise_capability, Promise* promise) {
@ -971,7 +973,7 @@ ThrowCompletionOr<NonnullGCPtr<Module>> VM::resolve_imported_module(ScriptOrModu
}
// 16.2.1.8 HostImportModuleDynamically ( referencingScriptOrModule, specifier, promiseCapability ), https://tc39.es/ecma262/#sec-hostimportmoduledynamically
void VM::import_module_dynamically(ScriptOrModule referencing_script_or_module, ModuleRequest module_request, PromiseCapability const& promise_capability)
ThrowCompletionOr<void> VM::import_module_dynamically(ScriptOrModule referencing_script_or_module, ModuleRequest module_request, PromiseCapability const& promise_capability)
{
auto& realm = *current_realm();
@ -1001,8 +1003,8 @@ void VM::import_module_dynamically(ScriptOrModule referencing_script_or_module,
// If there is no ScriptOrModule in any of the execution contexts
if (referencing_script_or_module.has<Empty>()) {
// Throw an error for now
promise->reject(InternalError::create(realm, String::formatted(ErrorType::ModuleNotFoundNoReferencingScript.message(), module_request.module_specifier).release_value_but_fixme_should_propagate_errors()));
return;
promise->reject(InternalError::create(realm, TRY_OR_THROW_OOM(*this, String::formatted(ErrorType::ModuleNotFoundNoReferencingScript.message(), module_request.module_specifier))));
return {};
}
}
@ -1026,6 +1028,7 @@ void VM::import_module_dynamically(ScriptOrModule referencing_script_or_module,
// It must return unused.
// Note: Just return void always since the resulting value cannot be accessed by user code.
return {};
}
// 16.2.1.9 FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, innerPromise ), https://tc39.es/ecma262/#sec-finishdynamicimport

View file

@ -250,7 +250,7 @@ public:
ScriptOrModule get_active_script_or_module() const;
Function<ThrowCompletionOr<NonnullGCPtr<Module>>(ScriptOrModule, ModuleRequest const&)> host_resolve_imported_module;
Function<void(ScriptOrModule, ModuleRequest, PromiseCapability const&)> host_import_module_dynamically;
Function<ThrowCompletionOr<void>(ScriptOrModule, ModuleRequest, PromiseCapability const&)> host_import_module_dynamically;
Function<void(ScriptOrModule, ModuleRequest const&, PromiseCapability const&, Promise*)> host_finish_dynamic_import;
Function<HashMap<PropertyKey, Value>(SourceTextModule const&)> host_get_import_meta_properties;
@ -277,7 +277,7 @@ private:
ThrowCompletionOr<NonnullGCPtr<Module>> resolve_imported_module(ScriptOrModule referencing_script_or_module, ModuleRequest const& module_request);
ThrowCompletionOr<void> link_and_eval_module(Module& module);
void import_module_dynamically(ScriptOrModule referencing_script_or_module, ModuleRequest module_request, PromiseCapability const& promise_capability);
ThrowCompletionOr<void> import_module_dynamically(ScriptOrModule referencing_script_or_module, ModuleRequest module_request, PromiseCapability const& promise_capability);
void finish_dynamic_import(ScriptOrModule referencing_script_or_module, ModuleRequest module_request, PromiseCapability const& promise_capability, Promise* inner_promise);
HashMap<String, PrimitiveString*> m_string_cache;