[d8] Verify host-defined options

d8 never checked what the actual value of the host-defined options are.
We now properly very that the host-defined options is a specific object
so we we don't end up accidentally ignoring a wrong options object.

Drive-by-fix:
- Convert %AbortJS argument to string

Bug: chromium:1244145
Change-Id: If0ed128d215682bcf066592418420548b06eb6a1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3259655
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77699}
This commit is contained in:
Camillo Bruni 2021-11-04 10:26:48 +01:00 committed by V8 LUCI CQ
parent 93973396ed
commit 0446ab7ce1
3 changed files with 56 additions and 15 deletions

View File

@ -644,9 +644,39 @@ MaybeLocal<T> Shell::CompileString(Isolate* isolate, Local<Context> context,
return result; return result;
} }
namespace {
// For testing.
const int kHostDefinedOptionsLength = 2;
const uint32_t kHostDefinedOptionsMagicConstant = 0xF1F2F3F0;
ScriptOrigin CreateScriptOrigin(Isolate* isolate, Local<String> resource_name,
v8::ScriptType type) {
Local<PrimitiveArray> options =
PrimitiveArray::New(isolate, kHostDefinedOptionsLength);
options->Set(isolate, 0,
v8::Uint32::New(isolate, kHostDefinedOptionsMagicConstant));
options->Set(isolate, 1, resource_name);
return ScriptOrigin(isolate, resource_name, 0, 0, false, -1, Local<Value>(),
false, false, type == v8::ScriptType::kModule, options);
}
bool IsValidHostDefinedOptions(Local<Context> context,
Local<PrimitiveArray> options,
Local<ScriptOrModule> script_or_module) {
Isolate* isolate = context->GetIsolate();
if (options->Length() != kHostDefinedOptionsLength) return false;
uint32_t magic = 0;
if (!options->Get(isolate, 0)->Uint32Value(context).To(&magic)) return false;
if (magic != kHostDefinedOptionsMagicConstant) return false;
return options->Get(isolate, 1)
.As<String>()
->StrictEquals(script_or_module->GetResourceName());
}
} // namespace
// Executes a string within the current v8 context. // Executes a string within the current v8 context.
bool Shell::ExecuteString(Isolate* isolate, Local<String> source, bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Value> name, PrintResult print_result, Local<String> name, PrintResult print_result,
ReportExceptions report_exceptions, ReportExceptions report_exceptions,
ProcessMessageQueue process_message_queue) { ProcessMessageQueue process_message_queue) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@ -702,9 +732,9 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
Local<Context> realm = Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]); Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm); Context::Scope context_scope(realm);
MaybeLocal<Script> maybe_script;
Local<Context> context(isolate->GetCurrentContext()); Local<Context> context(isolate->GetCurrentContext());
ScriptOrigin origin(isolate, name); ScriptOrigin origin =
CreateScriptOrigin(isolate, name, ScriptType::kClassic);
for (int i = 1; i < options.repeat_compile; ++i) { for (int i = 1; i < options.repeat_compile; ++i) {
HandleScope handle_scope_for_compiling(isolate); HandleScope handle_scope_for_compiling(isolate);
@ -1005,9 +1035,11 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Module> referrer,
v8::String::NewFromUtf8(isolate, msg.c_str()).ToLocalChecked()); v8::String::NewFromUtf8(isolate, msg.c_str()).ToLocalChecked());
return MaybeLocal<Module>(); return MaybeLocal<Module>();
} }
ScriptOrigin origin(
isolate, String::NewFromUtf8(isolate, file_name.c_str()).ToLocalChecked(), Local<String> resource_name =
0, 0, false, -1, Local<Value>(), false, false, true); String::NewFromUtf8(isolate, file_name.c_str()).ToLocalChecked();
ScriptOrigin origin =
CreateScriptOrigin(isolate, resource_name, ScriptType::kModule);
Local<Module> module; Local<Module> module;
if (module_type == ModuleType::kJavaScript) { if (module_type == ModuleType::kJavaScript) {
@ -1192,16 +1224,24 @@ MaybeLocal<Promise> Shell::HostImportModuleDynamically(
MaybeLocal<Promise::Resolver> maybe_resolver = MaybeLocal<Promise::Resolver> maybe_resolver =
Promise::Resolver::New(context); Promise::Resolver::New(context);
Local<Promise::Resolver> resolver; Local<Promise::Resolver> resolver;
if (maybe_resolver.ToLocal(&resolver)) { if (!maybe_resolver.ToLocal(&resolver)) return MaybeLocal<Promise>();
Local<PrimitiveArray> host_defined_options =
script_or_module->GetHostDefinedOptions();
if (!IsValidHostDefinedOptions(context, host_defined_options,
script_or_module)) {
resolver
->Reject(context, v8::Exception::TypeError(String::NewFromUtf8Literal(
isolate, "Invalid host defined options")))
.ToChecked();
} else {
DynamicImportData* data = new DynamicImportData( DynamicImportData* data = new DynamicImportData(
isolate, script_or_module->GetResourceName().As<String>(), specifier, isolate, script_or_module->GetResourceName().As<String>(), specifier,
import_assertions, resolver); import_assertions, resolver);
PerIsolateData::Get(isolate)->AddDynamicImportData(data); PerIsolateData::Get(isolate)->AddDynamicImportData(data);
isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data); isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data);
return resolver->GetPromise();
} }
return resolver->GetPromise();
return MaybeLocal<Promise>();
} }
void Shell::HostInitializeImportMetaObject(Local<Context> context, void Shell::HostInitializeImportMetaObject(Local<Context> context,
@ -1830,9 +1870,10 @@ void Shell::RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args) {
isolate->ThrowError("Invalid argument"); isolate->ThrowError("Invalid argument");
return; return;
} }
ScriptOrigin origin(isolate, ScriptOrigin origin =
String::NewFromUtf8Literal(isolate, "(d8)", CreateScriptOrigin(isolate, String::NewFromUtf8Literal(isolate, "(d8)"),
NewStringType::kInternalized)); ScriptType::kClassic);
ScriptCompiler::Source script_source(source, origin); ScriptCompiler::Source script_source(source, origin);
Local<UnboundScript> script; Local<UnboundScript> script;
if (!ScriptCompiler::CompileUnboundScript(isolate, &script_source) if (!ScriptCompiler::CompileUnboundScript(isolate, &script_source)

View File

@ -462,7 +462,7 @@ class Shell : public i::AllStatic {
enum class CodeType { kFileName, kString, kFunction, kInvalid, kNone }; enum class CodeType { kFileName, kString, kFunction, kInvalid, kNone };
static bool ExecuteString(Isolate* isolate, Local<String> source, static bool ExecuteString(Isolate* isolate, Local<String> source,
Local<Value> name, PrintResult print_result, Local<String> name, PrintResult print_result,
ReportExceptions report_exceptions, ReportExceptions report_exceptions,
ProcessMessageQueue process_message_queue); ProcessMessageQueue process_message_queue);
static bool ExecuteModule(Isolate* isolate, const char* file_name); static bool ExecuteModule(Isolate* isolate, const char* file_name);

View File

@ -10,7 +10,7 @@ async function f(assert) {
try { try {
module_namespace_obj = await import('modules-skip-1.mjs'); module_namespace_obj = await import('modules-skip-1.mjs');
} catch(e) { } catch(e) {
%AbortJS(e); %AbortJS(e.ToString());
} }
class A { class A {