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

Side by Side Diff: extensions/renderer/object_backed_native_handler.cc

Issue 1964483002: Revert of [Extensions] Update more bindings and allow for multiple feature access (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
31 // Key for the base::Bound routed function. 24 // Key for the base::Bound routed function.
32 const char* kHandlerFunction = "handler_function"; 25 const char* kHandlerFunction = "handler_function";
33 26 const char* kFeatureName = "feature_name";
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
71 } // namespace 27 } // namespace
72 28
73 ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context) 29 ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context)
74 : router_data_(context->isolate()), 30 : router_data_(context->isolate()),
75 context_(context), 31 context_(context),
76 object_template_(context->isolate(), 32 object_template_(context->isolate(),
77 v8::ObjectTemplate::New(context->isolate())) { 33 v8::ObjectTemplate::New(context->isolate())) {
78 } 34 }
79 35
80 ObjectBackedNativeHandler::~ObjectBackedNativeHandler() { 36 ObjectBackedNativeHandler::~ObjectBackedNativeHandler() {
81 } 37 }
82 38
83 v8::Local<v8::Object> ObjectBackedNativeHandler::NewInstance() { 39 v8::Local<v8::Object> ObjectBackedNativeHandler::NewInstance() {
84 return v8::Local<v8::ObjectTemplate>::New(GetIsolate(), object_template_) 40 return v8::Local<v8::ObjectTemplate>::New(GetIsolate(), object_template_)
85 ->NewInstance(); 41 ->NewInstance();
86 } 42 }
87 43
88 // static 44 // static
89 void ObjectBackedNativeHandler::Router( 45 void ObjectBackedNativeHandler::Router(
90 const v8::FunctionCallbackInfo<v8::Value>& args) { 46 const v8::FunctionCallbackInfo<v8::Value>& args) {
91 v8::Isolate* isolate = args.GetIsolate(); 47 v8::Isolate* isolate = args.GetIsolate();
92 v8::HandleScope handle_scope(isolate); 48 v8::HandleScope handle_scope(isolate);
93 v8::Local<v8::Object> data = args.Data().As<v8::Object>(); 49 v8::Local<v8::Object> data = args.Data().As<v8::Object>();
94 v8::Local<v8::Context> context = isolate->GetCurrentContext(); 50 v8::Local<v8::Context> context = isolate->GetCurrentContext();
95 51
96 v8::Local<v8::Value> handler_function_value; 52 v8::Local<v8::Value> handler_function_value;
53 v8::Local<v8::Value> feature_name_value;
97 // See comment in header file for why we do this. 54 // See comment in header file for why we do this.
98 if (!GetPrivate(context, data, kHandlerFunction, &handler_function_value) || 55 if (!GetPrivate(context, data, kHandlerFunction, &handler_function_value) ||
99 handler_function_value->IsUndefined()) { 56 handler_function_value->IsUndefined() ||
57 !GetPrivate(context, data, kFeatureName, &feature_name_value) ||
58 !feature_name_value->IsString()) {
100 ScriptContext* script_context = 59 ScriptContext* script_context =
101 ScriptContextSet::GetContextByV8Context(context); 60 ScriptContextSet::GetContextByV8Context(context);
102 console::Error(script_context ? script_context->GetRenderFrame() : nullptr, 61 console::Error(script_context ? script_context->GetRenderFrame() : nullptr,
103 "Extension view no longer exists"); 62 "Extension view no longer exists");
104 return; 63 return;
105 } 64 }
106 65
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 }
107 // This CHECK is *important*. Otherwise, we'll go around happily executing 87 // This CHECK is *important*. Otherwise, we'll go around happily executing
108 // something random. See crbug.com/548273. 88 // something random. See crbug.com/548273.
109 CHECK(handler_function_value->IsExternal()); 89 CHECK(handler_function_value->IsExternal());
110 static_cast<HandlerFunctionCheck*>( 90 static_cast<HandlerFunction*>(
111 handler_function_value.As<v8::External>()->Value())->Run(args, context); 91 handler_function_value.As<v8::External>()->Value())->Run(args);
112 92
113 // Verify that the return value, if any, is accessible by the context. 93 // Verify that the return value, if any, is accessible by the context.
114 v8::ReturnValue<v8::Value> ret = args.GetReturnValue(); 94 v8::ReturnValue<v8::Value> ret = args.GetReturnValue();
115 v8::Local<v8::Value> ret_value = ret.Get(); 95 v8::Local<v8::Value> ret_value = ret.Get();
116 if (ret_value->IsObject() && !ret_value->IsNull() && 96 if (ret_value->IsObject() && !ret_value->IsNull() &&
117 !ContextCanAccessObject(context, v8::Local<v8::Object>::Cast(ret_value), 97 !ContextCanAccessObject(context, v8::Local<v8::Object>::Cast(ret_value),
118 true)) { 98 true)) {
119 NOTREACHED() << "Insecure return value"; 99 NOTREACHED() << "Insecure return value";
120 ret.SetUndefined(); 100 ret.SetUndefined();
121 } 101 }
122 } 102 }
123 103
124 void ObjectBackedNativeHandler::RouteFunction( 104 void ObjectBackedNativeHandler::RouteFunction(
125 const std::string& name, 105 const std::string& name,
126 const HandlerFunction& handler_function) { 106 const HandlerFunction& handler_function) {
127 RouteFunction(name, std::vector<std::string>(), handler_function); 107 RouteFunction(name, "", handler_function);
128 } 108 }
129 109
130 void ObjectBackedNativeHandler::RouteFunction( 110 void ObjectBackedNativeHandler::RouteFunction(
131 const std::string& name, 111 const std::string& name,
132 const std::string& feature_name, 112 const std::string& feature_name,
133 const HandlerFunction& handler_function) { 113 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) {
142 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 114 v8::Isolate* isolate = v8::Isolate::GetCurrent();
143 v8::HandleScope handle_scope(isolate); 115 v8::HandleScope handle_scope(isolate);
144 v8::Context::Scope context_scope(context_->v8_context()); 116 v8::Context::Scope context_scope(context_->v8_context());
145 117
146 v8::Local<v8::Object> data = v8::Object::New(isolate); 118 v8::Local<v8::Object> data = v8::Object::New(isolate);
147 HandlerFunctionCheck check =
148 base::Bind(&ValidateAndCall, handler_function, features);
149 SetPrivate(data, kHandlerFunction, 119 SetPrivate(data, kHandlerFunction,
150 v8::External::New(isolate, new HandlerFunctionCheck(check))); 120 v8::External::New(isolate, new HandlerFunction(handler_function)));
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));
151 v8::Local<v8::FunctionTemplate> function_template = 126 v8::Local<v8::FunctionTemplate> function_template =
152 v8::FunctionTemplate::New(isolate, Router, data); 127 v8::FunctionTemplate::New(isolate, Router, data);
153 v8::Local<v8::ObjectTemplate>::New(isolate, object_template_) 128 v8::Local<v8::ObjectTemplate>::New(isolate, object_template_)
154 ->Set(isolate, name.c_str(), function_template); 129 ->Set(isolate, name.c_str(), function_template);
155 router_data_.Append(data); 130 router_data_.Append(data);
156 } 131 }
157 132
158 v8::Isolate* ObjectBackedNativeHandler::GetIsolate() const { 133 v8::Isolate* ObjectBackedNativeHandler::GetIsolate() const {
159 return context_->isolate(); 134 return context_->isolate();
160 } 135 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 v8::Local<v8::Object> obj, 217 v8::Local<v8::Object> obj,
243 const char* key) { 218 const char* key) {
244 obj->DeletePrivate(context, 219 obj->DeletePrivate(context,
245 v8::Private::ForApi( 220 v8::Private::ForApi(
246 context->GetIsolate(), 221 context->GetIsolate(),
247 v8::String::NewFromUtf8(context->GetIsolate(), key))) 222 v8::String::NewFromUtf8(context->GetIsolate(), key)))
248 .FromJust(); 223 .FromJust();
249 } 224 }
250 225
251 } // namespace extensions 226 } // 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