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

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

Issue 2583273002: [Extensions Bindings] Allow for argument validation without conversion (Closed)
Patch Set: format Created 3 years, 12 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/api_binding_hooks.h" 5 #include "extensions/renderer/api_binding_hooks.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/supports_user_data.h" 9 #include "base/supports_user_data.h"
10 #include "extensions/renderer/api_signature.h"
10 #include "gin/arguments.h" 11 #include "gin/arguments.h"
11 #include "gin/handle.h" 12 #include "gin/handle.h"
12 #include "gin/object_template_builder.h" 13 #include "gin/object_template_builder.h"
13 #include "gin/per_context_data.h" 14 #include "gin/per_context_data.h"
14 #include "gin/wrappable.h" 15 #include "gin/wrappable.h"
15 16
16 namespace extensions { 17 namespace extensions {
17 18
18 namespace { 19 namespace {
19 20
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!"; 123 DCHECK(!hooks_used_) << "Hooks must be registered before the first use!";
123 request_hooks_[method_name] = hook; 124 request_hooks_[method_name] = hook;
124 } 125 }
125 126
126 void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source, 127 void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source,
127 v8::Global<v8::String> resource_name) { 128 v8::Global<v8::String> resource_name) {
128 js_hooks_source_ = std::move(source); 129 js_hooks_source_ = std::move(source);
129 js_resource_name_ = std::move(resource_name); 130 js_resource_name_ = std::move(resource_name);
130 } 131 }
131 132
132 bool APIBindingHooks::HandleRequest(const std::string& api_name, 133 APIBindingHooks::RequestResult APIBindingHooks::HandleRequest(
133 const std::string& method_name, 134 const std::string& api_name,
134 v8::Local<v8::Context> context, 135 const std::string& method_name,
135 const APISignature* signature, 136 v8::Local<v8::Context> context,
136 gin::Arguments* arguments) { 137 const APISignature* signature,
138 gin::Arguments* arguments,
139 const ArgumentSpec::RefMap& type_refs) {
137 // Easy case: a native custom hook. 140 // Easy case: a native custom hook.
138 auto request_hooks_iter = request_hooks_.find(method_name); 141 auto request_hooks_iter = request_hooks_.find(method_name);
139 if (request_hooks_iter != request_hooks_.end()) { 142 if (request_hooks_iter != request_hooks_.end()) {
140 request_hooks_iter->second.Run(signature, arguments); 143 RequestResult result =
141 return true; 144 request_hooks_iter->second.Run(signature, arguments, type_refs);
145 // Right now, it doesn't make sense to register a request handler that
146 // doesn't handle the request.
147 DCHECK_NE(RequestResult::NOT_HANDLED, result);
148 return result;
142 } 149 }
143 150
144 // Harder case: looking up a custom hook registered on the context (since 151 // Harder case: looking up a custom hook registered on the context (since
145 // these are JS, each context has a separate instance). 152 // these are JS, each context has a separate instance).
146 gin::PerContextData* per_context_data = gin::PerContextData::From(context); 153 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
147 DCHECK(per_context_data); 154 DCHECK(per_context_data);
148 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>( 155 APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>(
149 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey)); 156 per_context_data->GetUserData(kExtensionAPIHooksPerContextKey));
150 if (!data) 157 if (!data)
151 return false; 158 return RequestResult::NOT_HANDLED;
152 159
153 auto hook_interface_iter = data->hook_interfaces.find(api_name); 160 auto hook_interface_iter = data->hook_interfaces.find(api_name);
154 if (hook_interface_iter == data->hook_interfaces.end()) 161 if (hook_interface_iter == data->hook_interfaces.end())
155 return false; 162 return RequestResult::NOT_HANDLED;
156 163
157 JSHookInterface* hook_interface = nullptr; 164 JSHookInterface* hook_interface = nullptr;
158 gin::Converter<JSHookInterface*>::FromV8( 165 gin::Converter<JSHookInterface*>::FromV8(
159 context->GetIsolate(), 166 context->GetIsolate(),
160 hook_interface_iter->second.Get(context->GetIsolate()), &hook_interface); 167 hook_interface_iter->second.Get(context->GetIsolate()), &hook_interface);
161 CHECK(hook_interface); 168 CHECK(hook_interface);
162 169
163 auto js_hook_iter = hook_interface->js_hooks()->find(method_name); 170 auto js_hook_iter = hook_interface->js_hooks()->find(method_name);
164 if (js_hook_iter == hook_interface->js_hooks()->end()) 171 if (js_hook_iter == hook_interface->js_hooks()->end())
165 return false; 172 return RequestResult::NOT_HANDLED;
166 173
167 // Found a JS handler. 174 // Found a JS handler.
168 std::vector<v8::Local<v8::Value>> v8_args; 175 std::vector<v8::Local<v8::Value>> v8_args;
176 std::string error;
177 if (!signature->ParseArgumentsToV8(arguments, type_refs, &v8_args, &error))
178 return RequestResult::INVALID_INVOCATION;
179
169 // TODO(devlin): Right now, this doesn't support exceptions or return values, 180 // TODO(devlin): Right now, this doesn't support exceptions or return values,
170 // which we will need to at some point. 181 // which we will need to at some point.
171 if (arguments->GetRemaining(&v8_args)) { 182 v8::Local<v8::Function> handler =
172 v8::Local<v8::Function> handler = 183 js_hook_iter->second.Get(context->GetIsolate());
173 js_hook_iter->second.Get(context->GetIsolate()); 184 run_js_.Run(handler, context, v8_args.size(), v8_args.data());
174 run_js_.Run(handler, context, v8_args.size(), v8_args.data());
175 }
176 185
177 return true; 186 return RequestResult::HANDLED;
178 } 187 }
179 188
180 void APIBindingHooks::InitializeInContext( 189 void APIBindingHooks::InitializeInContext(
181 v8::Local<v8::Context> context, 190 v8::Local<v8::Context> context,
182 const std::string& api_name) { 191 const std::string& api_name) {
183 if (js_hooks_source_.IsEmpty()) 192 if (js_hooks_source_.IsEmpty())
184 return; 193 return;
185 194
186 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate()); 195 v8::Local<v8::String> source = js_hooks_source_.Get(context->GetIsolate());
187 v8::Local<v8::String> resource_name = 196 v8::Local<v8::String> resource_name =
188 js_resource_name_.Get(context->GetIsolate()); 197 js_resource_name_.Get(context->GetIsolate());
189 v8::Local<v8::Script> script; 198 v8::Local<v8::Script> script;
190 v8::ScriptOrigin origin(resource_name); 199 v8::ScriptOrigin origin(resource_name);
191 if (!v8::Script::Compile(context, source, &origin).ToLocal(&script)) 200 if (!v8::Script::Compile(context, source, &origin).ToLocal(&script))
192 return; 201 return;
193 v8::Local<v8::Value> func_as_value = script->Run(); 202 v8::Local<v8::Value> func_as_value = script->Run();
194 v8::Local<v8::Function> function; 203 v8::Local<v8::Function> function;
195 if (!gin::ConvertFromV8(context->GetIsolate(), func_as_value, &function)) 204 if (!gin::ConvertFromV8(context->GetIsolate(), func_as_value, &function))
196 return; 205 return;
197 v8::Local<v8::Object> api_hooks = CreateJSHookInterface(api_name, context); 206 v8::Local<v8::Object> api_hooks = CreateJSHookInterface(api_name, context);
198 v8::Local<v8::Value> args[] = {api_hooks}; 207 v8::Local<v8::Value> args[] = {api_hooks};
199 run_js_.Run(function, context, arraysize(args), args); 208 run_js_.Run(function, context, arraysize(args), args);
200 } 209 }
201 210
202 } // namespace extensions 211 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698