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

Unified Diff: extensions/renderer/object_backed_native_handler.cc

Issue 1945433002: [Extensions] Update more bindings and allow for multiple feature access (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Antony's Created 4 years, 7 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/object_backed_native_handler.h ('k') | extensions/renderer/set_icon_natives.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/object_backed_native_handler.cc
diff --git a/extensions/renderer/object_backed_native_handler.cc b/extensions/renderer/object_backed_native_handler.cc
index 3728543d2be924e1d91fb9c3acb6c11e3f8c3270..2248e0605e092512f478af6cd55424bb90aaacb3 100644
--- a/extensions/renderer/object_backed_native_handler.cc
+++ b/extensions/renderer/object_backed_native_handler.cc
@@ -21,9 +21,53 @@
namespace extensions {
namespace {
+
+// A wrapper around a handler function that will check if the context is allowed
+// before passing the arguments to the handler function.
+using HandlerFunctionCheck =
+ base::Callback<void(const v8::FunctionCallbackInfo<v8::Value>&,
+ const v8::Local<v8::Context>&)>;
+
// Key for the base::Bound routed function.
const char* kHandlerFunction = "handler_function";
-const char* kFeatureName = "feature_name";
+
+// Checks whether a given |context| has any of the |allowed_features|. This
+// treats an empty |allowed_features| as indicating that any context has access.
+bool IsContextAllowed(const std::vector<std::string>& allowed_features,
+ const v8::Local<v8::Context>& context) {
+ // We can't access the ScriptContextSet on a worker thread. Luckily, we also
+ // don't inject many bindings into worker threads.
+ // TODO(devlin): Figure out a way around this.
+ if (content::WorkerThread::GetCurrentId() == 0)
+ return true;
+ if (allowed_features.empty())
+ return true;
+ ScriptContext* script_context =
+ ScriptContextSet::GetContextByV8Context(context);
+ // TODO(devlin): Eventually, we should fail if script_context is null.
+ if (!script_context)
+ return true;
+ for (const std::string& feature : allowed_features) {
+ if (script_context->GetAvailability(feature).is_available())
+ return true;
+ }
+
+ return false;
+}
+
+// Checks whether the given |context| has access to any of the necessary
+// |allowed_features| and calls |function|.
+void ValidateAndCall(const ObjectBackedNativeHandler::HandlerFunction& function,
+ const std::vector<std::string>& allowed_features,
+ const v8::FunctionCallbackInfo<v8::Value>& args,
+ const v8::Local<v8::Context>& context) {
+ if (!IsContextAllowed(allowed_features, context)) {
+ NOTREACHED();
+ return;
+ }
+ function.Run(args);
+}
+
} // namespace
ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context)
@@ -50,12 +94,9 @@ void ObjectBackedNativeHandler::Router(
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::Value> handler_function_value;
- v8::Local<v8::Value> feature_name_value;
// See comment in header file for why we do this.
if (!GetPrivate(context, data, kHandlerFunction, &handler_function_value) ||
- handler_function_value->IsUndefined() ||
- !GetPrivate(context, data, kFeatureName, &feature_name_value) ||
- !feature_name_value->IsString()) {
+ handler_function_value->IsUndefined()) {
ScriptContext* script_context =
ScriptContextSet::GetContextByV8Context(context);
console::Error(script_context ? script_context->GetRenderFrame() : nullptr,
@@ -63,32 +104,11 @@ void ObjectBackedNativeHandler::Router(
return;
}
- // We can't access the ScriptContextSet on a worker thread. Luckily, we also
- // don't inject many bindings into worker threads.
- // TODO(devlin): Figure out a way around this.
- if (content::WorkerThread::GetCurrentId() == 0) {
- ScriptContext* script_context =
- ScriptContextSet::GetContextByV8Context(context);
- v8::Local<v8::String> feature_name_string =
- feature_name_value->ToString(context).ToLocalChecked();
- std::string feature_name = *v8::String::Utf8Value(feature_name_string);
- // TODO(devlin): Eventually, we should fail if either script_context is null
- // or feature_name is empty.
- if (script_context && !feature_name.empty()) {
- Feature::Availability availability =
- script_context->GetAvailability(feature_name);
- if (!availability.is_available()) {
- DVLOG(1) << feature_name
- << " is not available: " << availability.message();
- return;
- }
- }
- }
// This CHECK is *important*. Otherwise, we'll go around happily executing
// something random. See crbug.com/548273.
CHECK(handler_function_value->IsExternal());
- static_cast<HandlerFunction*>(
- handler_function_value.As<v8::External>()->Value())->Run(args);
+ static_cast<HandlerFunctionCheck*>(
+ handler_function_value.As<v8::External>()->Value())->Run(args, context);
// Verify that the return value, if any, is accessible by the context.
v8::ReturnValue<v8::Value> ret = args.GetReturnValue();
@@ -104,25 +124,30 @@ void ObjectBackedNativeHandler::Router(
void ObjectBackedNativeHandler::RouteFunction(
const std::string& name,
const HandlerFunction& handler_function) {
- RouteFunction(name, "", handler_function);
+ RouteFunction(name, std::vector<std::string>(), handler_function);
}
void ObjectBackedNativeHandler::RouteFunction(
const std::string& name,
const std::string& feature_name,
const HandlerFunction& handler_function) {
+ RouteFunction(
+ name, std::vector<std::string>(1, feature_name), handler_function);
+}
+
+void ObjectBackedNativeHandler::RouteFunction(
+ const std::string& name,
+ const std::vector<std::string>& features,
+ const HandlerFunction& handler_function) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context_->v8_context());
v8::Local<v8::Object> data = v8::Object::New(isolate);
+ HandlerFunctionCheck check =
+ base::Bind(&ValidateAndCall, handler_function, features);
SetPrivate(data, kHandlerFunction,
- v8::External::New(isolate, new HandlerFunction(handler_function)));
- DCHECK(feature_name.empty() ||
- ExtensionAPI::GetSharedInstance()->GetFeatureDependency(feature_name))
- << feature_name;
- SetPrivate(data, kFeatureName,
- v8_helpers::ToV8StringUnsafe(isolate, feature_name));
+ v8::External::New(isolate, new HandlerFunctionCheck(check)));
v8::Local<v8::FunctionTemplate> function_template =
v8::FunctionTemplate::New(isolate, Router, data);
v8::Local<v8::ObjectTemplate>::New(isolate, object_template_)
« no previous file with comments | « extensions/renderer/object_backed_native_handler.h ('k') | extensions/renderer/set_icon_natives.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698