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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/object_backed_native_handler.h" 5 #include "extensions/renderer/object_backed_native_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/linked_ptr.h" 10 #include "base/memory/linked_ptr.h"
11 #include "content/public/child/worker_thread.h" 11 #include "content/public/child/worker_thread.h"
12 #include "extensions/common/extension_api.h" 12 #include "extensions/common/extension_api.h"
13 #include "extensions/renderer/console.h" 13 #include "extensions/renderer/console.h"
14 #include "extensions/renderer/module_system.h" 14 #include "extensions/renderer/module_system.h"
15 #include "extensions/renderer/script_context.h" 15 #include "extensions/renderer/script_context.h"
16 #include "extensions/renderer/script_context_set.h" 16 #include "extensions/renderer/script_context_set.h"
17 #include "extensions/renderer/v8_helpers.h" 17 #include "extensions/renderer/v8_helpers.h"
18 #include "third_party/WebKit/public/web/WebLocalFrame.h" 18 #include "third_party/WebKit/public/web/WebLocalFrame.h"
19 #include "v8/include/v8.h" 19 #include "v8/include/v8.h"
20 20
21 namespace extensions { 21 namespace extensions {
22 22
23 namespace { 23 namespace {
24
25 // A wrapper around a handler function that will check if the context is allowed
26 // before passing the arguments to the handler function.
27 using HandlerFunctionCheck =
28 base::Callback<void(const v8::FunctionCallbackInfo<v8::Value>&,
29 const v8::Local<v8::Context>&)>;
30
24 // Key for the base::Bound routed function. 31 // Key for the base::Bound routed function.
25 const char* kHandlerFunction = "handler_function"; 32 const char* kHandlerFunction = "handler_function";
26 const char* kFeatureName = "feature_name"; 33
34 // Checks whether a given |context| has any of the |allowed_features|. This
35 // treats an empty |allowed_features| as indicating that any context has access.
36 bool IsContextAllowed(const std::vector<std::string>& allowed_features,
37 const v8::Local<v8::Context>& context) {
38 // We can't access the ScriptContextSet on a worker thread. Luckily, we also
39 // don't inject many bindings into worker threads.
40 // TODO(devlin): Figure out a way around this.
41 if (content::WorkerThread::GetCurrentId() == 0)
42 return true;
43 if (allowed_features.empty())
44 return true;
45 ScriptContext* script_context =
46 ScriptContextSet::GetContextByV8Context(context);
47 // TODO(devlin): Eventually, we should fail if script_context is null.
48 if (!script_context)
49 return true;
50 for (const std::string& feature : allowed_features) {
51 if (script_context->GetAvailability(feature).is_available())
52 return true;
53 }
54
55 return false;
56 }
57
58 // Checks whether the given |context| has access to any of the necessary
59 // |allowed_features| and calls |function|.
60 void ValidateAndCall(const ObjectBackedNativeHandler::HandlerFunction& function,
61 const std::vector<std::string>& allowed_features,
62 const v8::FunctionCallbackInfo<v8::Value>& args,
63 const v8::Local<v8::Context>& context) {
64 if (!IsContextAllowed(allowed_features, context)) {
65 NOTREACHED();
66 return;
67 }
68 function.Run(args);
69 }
70
27 } // namespace 71 } // namespace
28 72
29 ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context) 73 ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context)
30 : router_data_(context->isolate()), 74 : router_data_(context->isolate()),
31 context_(context), 75 context_(context),
32 object_template_(context->isolate(), 76 object_template_(context->isolate(),
33 v8::ObjectTemplate::New(context->isolate())) { 77 v8::ObjectTemplate::New(context->isolate())) {
34 } 78 }
35 79
36 ObjectBackedNativeHandler::~ObjectBackedNativeHandler() { 80 ObjectBackedNativeHandler::~ObjectBackedNativeHandler() {
37 } 81 }
38 82
39 v8::Local<v8::Object> ObjectBackedNativeHandler::NewInstance() { 83 v8::Local<v8::Object> ObjectBackedNativeHandler::NewInstance() {
40 return v8::Local<v8::ObjectTemplate>::New(GetIsolate(), object_template_) 84 return v8::Local<v8::ObjectTemplate>::New(GetIsolate(), object_template_)
41 ->NewInstance(); 85 ->NewInstance();
42 } 86 }
43 87
44 // static 88 // static
45 void ObjectBackedNativeHandler::Router( 89 void ObjectBackedNativeHandler::Router(
46 const v8::FunctionCallbackInfo<v8::Value>& args) { 90 const v8::FunctionCallbackInfo<v8::Value>& args) {
47 v8::Isolate* isolate = args.GetIsolate(); 91 v8::Isolate* isolate = args.GetIsolate();
48 v8::HandleScope handle_scope(isolate); 92 v8::HandleScope handle_scope(isolate);
49 v8::Local<v8::Object> data = args.Data().As<v8::Object>(); 93 v8::Local<v8::Object> data = args.Data().As<v8::Object>();
50 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 94 v8::Local<v8::Context> context = isolate->GetCurrentContext();
51 95
52 v8::Local<v8::Value> handler_function_value; 96 v8::Local<v8::Value> handler_function_value;
53 v8::Local<v8::Value> feature_name_value;
54 // See comment in header file for why we do this. 97 // See comment in header file for why we do this.
55 if (!GetPrivate(context, data, kHandlerFunction, &handler_function_value) || 98 if (!GetPrivate(context, data, kHandlerFunction, &handler_function_value) ||
56 handler_function_value->IsUndefined() || 99 handler_function_value->IsUndefined()) {
57 !GetPrivate(context, data, kFeatureName, &feature_name_value) ||
58 !feature_name_value->IsString()) {
59 ScriptContext* script_context = 100 ScriptContext* script_context =
60 ScriptContextSet::GetContextByV8Context(context); 101 ScriptContextSet::GetContextByV8Context(context);
61 console::Error(script_context ? script_context->GetRenderFrame() : nullptr, 102 console::Error(script_context ? script_context->GetRenderFrame() : nullptr,
62 "Extension view no longer exists"); 103 "Extension view no longer exists");
63 return; 104 return;
64 } 105 }
65 106
66 // We can't access the ScriptContextSet on a worker thread. Luckily, we also
67 // don't inject many bindings into worker threads.
68 // TODO(devlin): Figure out a way around this.
69 if (content::WorkerThread::GetCurrentId() == 0) {
70 ScriptContext* script_context =
71 ScriptContextSet::GetContextByV8Context(context);
72 v8::Local<v8::String> feature_name_string =
73 feature_name_value->ToString(context).ToLocalChecked();
74 std::string feature_name = *v8::String::Utf8Value(feature_name_string);
75 // TODO(devlin): Eventually, we should fail if either script_context is null
76 // or feature_name is empty.
77 if (script_context && !feature_name.empty()) {
78 Feature::Availability availability =
79 script_context->GetAvailability(feature_name);
80 if (!availability.is_available()) {
81 DVLOG(1) << feature_name
82 << " is not available: " << availability.message();
83 return;
84 }
85 }
86 }
87 // This CHECK is *important*. Otherwise, we'll go around happily executing 107 // This CHECK is *important*. Otherwise, we'll go around happily executing
88 // something random. See crbug.com/548273. 108 // something random. See crbug.com/548273.
89 CHECK(handler_function_value->IsExternal()); 109 CHECK(handler_function_value->IsExternal());
90 static_cast<HandlerFunction*>( 110 static_cast<HandlerFunctionCheck*>(
91 handler_function_value.As<v8::External>()->Value())->Run(args); 111 handler_function_value.As<v8::External>()->Value())->Run(args, context);
92 112
93 // Verify that the return value, if any, is accessible by the context. 113 // Verify that the return value, if any, is accessible by the context.
94 v8::ReturnValue<v8::Value> ret = args.GetReturnValue(); 114 v8::ReturnValue<v8::Value> ret = args.GetReturnValue();
95 v8::Local<v8::Value> ret_value = ret.Get(); 115 v8::Local<v8::Value> ret_value = ret.Get();
96 if (ret_value->IsObject() && !ret_value->IsNull() && 116 if (ret_value->IsObject() && !ret_value->IsNull() &&
97 !ContextCanAccessObject(context, v8::Local<v8::Object>::Cast(ret_value), 117 !ContextCanAccessObject(context, v8::Local<v8::Object>::Cast(ret_value),
98 true)) { 118 true)) {
99 NOTREACHED() << "Insecure return value"; 119 NOTREACHED() << "Insecure return value";
100 ret.SetUndefined(); 120 ret.SetUndefined();
101 } 121 }
102 } 122 }
103 123
104 void ObjectBackedNativeHandler::RouteFunction( 124 void ObjectBackedNativeHandler::RouteFunction(
105 const std::string& name, 125 const std::string& name,
106 const HandlerFunction& handler_function) { 126 const HandlerFunction& handler_function) {
107 RouteFunction(name, "", handler_function); 127 RouteFunction(name, std::vector<std::string>(), handler_function);
108 } 128 }
109 129
110 void ObjectBackedNativeHandler::RouteFunction( 130 void ObjectBackedNativeHandler::RouteFunction(
111 const std::string& name, 131 const std::string& name,
112 const std::string& feature_name, 132 const std::string& feature_name,
113 const HandlerFunction& handler_function) { 133 const HandlerFunction& handler_function) {
134 RouteFunction(
135 name, std::vector<std::string>(1, feature_name), handler_function);
136 }
137
138 void ObjectBackedNativeHandler::RouteFunction(
139 const std::string& name,
140 const std::vector<std::string>& features,
141 const HandlerFunction& handler_function) {
114 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 142 v8::Isolate* isolate = v8::Isolate::GetCurrent();
115 v8::HandleScope handle_scope(isolate); 143 v8::HandleScope handle_scope(isolate);
116 v8::Context::Scope context_scope(context_->v8_context()); 144 v8::Context::Scope context_scope(context_->v8_context());
117 145
118 v8::Local<v8::Object> data = v8::Object::New(isolate); 146 v8::Local<v8::Object> data = v8::Object::New(isolate);
147 HandlerFunctionCheck check =
148 base::Bind(&ValidateAndCall, handler_function, features);
119 SetPrivate(data, kHandlerFunction, 149 SetPrivate(data, kHandlerFunction,
120 v8::External::New(isolate, new HandlerFunction(handler_function))); 150 v8::External::New(isolate, new HandlerFunctionCheck(check)));
121 DCHECK(feature_name.empty() ||
122 ExtensionAPI::GetSharedInstance()->GetFeatureDependency(feature_name))
123 << feature_name;
124 SetPrivate(data, kFeatureName,
125 v8_helpers::ToV8StringUnsafe(isolate, feature_name));
126 v8::Local<v8::FunctionTemplate> function_template = 151 v8::Local<v8::FunctionTemplate> function_template =
127 v8::FunctionTemplate::New(isolate, Router, data); 152 v8::FunctionTemplate::New(isolate, Router, data);
128 v8::Local<v8::ObjectTemplate>::New(isolate, object_template_) 153 v8::Local<v8::ObjectTemplate>::New(isolate, object_template_)
129 ->Set(isolate, name.c_str(), function_template); 154 ->Set(isolate, name.c_str(), function_template);
130 router_data_.Append(data); 155 router_data_.Append(data);
131 } 156 }
132 157
133 v8::Isolate* ObjectBackedNativeHandler::GetIsolate() const { 158 v8::Isolate* ObjectBackedNativeHandler::GetIsolate() const {
134 return context_->isolate(); 159 return context_->isolate();
135 } 160 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 v8::Local<v8::Object> obj, 242 v8::Local<v8::Object> obj,
218 const char* key) { 243 const char* key) {
219 obj->DeletePrivate(context, 244 obj->DeletePrivate(context,
220 v8::Private::ForApi( 245 v8::Private::ForApi(
221 context->GetIsolate(), 246 context->GetIsolate(),
222 v8::String::NewFromUtf8(context->GetIsolate(), key))) 247 v8::String::NewFromUtf8(context->GetIsolate(), key)))
223 .FromJust(); 248 .FromJust();
224 } 249 }
225 250
226 } // namespace extensions 251 } // namespace extensions
OLDNEW
« 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