Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(589)

Unified Diff: extensions/renderer/module_system.cc

Issue 2936213002: [Extensions] Don't require() a module for calling a method (Closed)
Patch Set: lazyboy's Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/module_system.h ('k') | extensions/renderer/utils_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/module_system.cc
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc
index 2349218a544884d9bd8b341915c78bcb5a4b8c03..07ec45a5ad851875fc8cbf7cbc69023f97e9225a 100644
--- a/extensions/renderer/module_system.cc
+++ b/extensions/renderer/module_system.cc
@@ -239,8 +239,8 @@ v8::MaybeLocal<v8::Object> ModuleSystem::Require(
if (!ToV8String(GetIsolate(), module_name, &v8_module_name))
return v8::MaybeLocal<v8::Object>();
v8::EscapableHandleScope handle_scope(GetIsolate());
- v8::Local<v8::Value> value = RequireForJsInner(
- v8_module_name);
+ v8::Local<v8::Value> value =
+ RequireForJsInner(v8_module_name, true /* create */);
if (value.IsEmpty() || !value->IsObject())
return v8::MaybeLocal<v8::Object>();
return handle_scope.Escape(value.As<v8::Object>());
@@ -253,11 +253,12 @@ void ModuleSystem::RequireForJs(
return;
}
v8::Local<v8::String> module_name = args[0].As<v8::String>();
- args.GetReturnValue().Set(RequireForJsInner(module_name));
+ args.GetReturnValue().Set(RequireForJsInner(module_name, true /* create */));
}
v8::Local<v8::Value> ModuleSystem::RequireForJsInner(
- v8::Local<v8::String> module_name) {
+ v8::Local<v8::String> module_name,
+ bool create) {
v8::EscapableHandleScope handle_scope(GetIsolate());
v8::Local<v8::Context> v8_context = context()->v8_context();
v8::Context::Scope context_scope(v8_context);
@@ -280,6 +281,9 @@ v8::Local<v8::Value> ModuleSystem::RequireForJsInner(
!exports->IsUndefined())
return handle_scope.Escape(exports);
+ if (!create)
+ return v8::Undefined(GetIsolate());
+
exports = LoadModule(*v8::String::Utf8Value(module_name));
SetPrivateProperty(v8_context, modules, module_name, exports);
return handle_scope.Escape(exports);
@@ -325,7 +329,12 @@ void ModuleSystem::CallModuleMethodSafe(
v8::Local<v8::Function> function =
GetModuleFunction(module_name, method_name);
if (function.IsEmpty()) {
- NOTREACHED() << "GetModuleFunction() returns empty function handle";
+ // This can legitimately happen when the module hasn't been loaded in the
+ // context (since GetModuleFunction() does not load an unloaded module).
+ // Typically, we won't do this, but we can in the case of, e.g., dispatching
+ // events (where we'll try to dispatch to each context in a process). In
+ // these cases, though, we can know that there are no listeners registered,
+ // since the event module hasn't been loaded.
return;
}
@@ -601,7 +610,7 @@ v8::MaybeLocal<v8::Object> ModuleSystem::RequireNativeFromString(
if (overridden_native_handlers_.count(native_name) > 0u) {
v8::Local<v8::Value> value = RequireForJsInner(
- ToV8StringUnsafe(GetIsolate(), native_name.c_str()));
+ ToV8StringUnsafe(GetIsolate(), native_name.c_str()), true /* create */);
if (value.IsEmpty() || !value->IsObject())
return v8::MaybeLocal<v8::Object>();
return value.As<v8::Object>();
@@ -858,22 +867,28 @@ v8::Local<v8::Function> ModuleSystem::GetModuleFunction(
const std::string& method_name) {
v8::Local<v8::String> v8_module_name;
v8::Local<v8::String> v8_method_name;
- v8::Local<v8::Function> function;
if (!ToV8String(GetIsolate(), module_name.c_str(), &v8_module_name) ||
!ToV8String(GetIsolate(), method_name.c_str(), &v8_method_name)) {
- return function;
+ return v8::Local<v8::Function>();
}
v8::Local<v8::Value> module;
- {
- NativesEnabledScope natives_enabled(this);
- module = RequireForJsInner(v8_module_name);
- }
+ // Important: don't create the module if it doesn't exist. Doing so would
+ // force a call into JS, which is something we want to avoid in case it has
+ // been suspended. Additionally, we should only be calling module methods for
+ // modules that have been instantiated.
+ bool create = false;
+ module = RequireForJsInner(v8_module_name, create);
+
+ // RequireForJsInner() returns Undefined in the case of a module not being
+ // loaded, since we don't create it here.
+ if (!module.IsEmpty() && module->IsUndefined())
+ return v8::Local<v8::Function>();
if (module.IsEmpty() || !module->IsObject()) {
Fatal(context_,
"Failed to get module " + module_name + " to call " + method_name);
- return function;
+ return v8::Local<v8::Function>();
}
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(module);
@@ -881,11 +896,10 @@ v8::Local<v8::Function> ModuleSystem::GetModuleFunction(
if (!GetProperty(context()->v8_context(), object, v8_method_name, &value) ||
!value->IsFunction()) {
Fatal(context_, module_name + "." + method_name + " is not a function");
- return function;
+ return v8::Local<v8::Function>();
}
- function = v8::Local<v8::Function>::Cast(value);
- return function;
+ return v8::Local<v8::Function>::Cast(value);
}
} // namespace extensions
« no previous file with comments | « extensions/renderer/module_system.h ('k') | extensions/renderer/utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698