Index: extensions/renderer/api_binding.cc |
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc |
index 163858dbc6503b311b05aaf14e20f6b44b196a14..218565b17821ff57a41e2f1f326a45db8787312b 100644 |
--- a/extensions/renderer/api_binding.cc |
+++ b/extensions/renderer/api_binding.cc |
@@ -188,36 +188,67 @@ void APIBinding::HandleCall(const std::string& name, |
// GetCurrentContext() should always be correct. |
v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
- APIBindingHooks::RequestResult hooks_result = |
- APIBindingHooks::RequestResult::NOT_HANDLED; |
- hooks_result = binding_hooks_->HandleRequest(api_name_, name, context, |
- signature, arguments, |
- *type_refs_); |
- |
- switch (hooks_result) { |
- case APIBindingHooks::RequestResult::INVALID_INVOCATION: |
- arguments->ThrowTypeError("Invalid invocation"); |
+ bool invalid_invocation = false; |
+ std::vector<v8::Local<v8::Value>> argument_list; |
+ { |
+ v8::TryCatch try_catch(isolate); |
+ invalid_invocation = arguments->Length() > 0 && |
+ !arguments->GetRemaining(&argument_list); |
+ if (try_catch.HasCaught()) { |
jbroman
2017/01/02 19:46:38
Why would this ever catch? Nothing about checking
Devlin
2017/01/04 17:57:02
Nope, shouldn't catch (and also should't fail). S
|
+ try_catch.ReThrow(); |
return; |
- case APIBindingHooks::RequestResult::HANDLED: |
- return; // Our work here is done. |
- case APIBindingHooks::RequestResult::NOT_HANDLED: |
- break; // Handle in the default manner. |
+ } |
+ } |
+ // Throw the type error here (rather than above when parsing) to avoid just |
+ // catching it. |
+ if (invalid_invocation) { |
+ arguments->ThrowTypeError("Invalid invocation"); |
+ return; |
+ } |
+ |
+ { |
+ v8::TryCatch try_catch(isolate); |
+ APIBindingHooks::RequestResult hooks_result = |
+ APIBindingHooks::RequestResult::NOT_HANDLED; |
+ hooks_result = binding_hooks_->HandleRequest(api_name_, name, context, |
+ signature, &argument_list, |
+ *type_refs_); |
+ |
+ switch (hooks_result) { |
+ case APIBindingHooks::RequestResult::INVALID_INVOCATION: |
+ invalid_invocation = true; |
+ // Throw a type error below so that it's not caught by our try-catch. |
+ break; |
+ case APIBindingHooks::RequestResult::THROWN: |
+ DCHECK(try_catch.HasCaught()); |
+ try_catch.ReThrow(); |
+ return; |
+ case APIBindingHooks::RequestResult::HANDLED: |
+ return; // Our work here is done. |
+ case APIBindingHooks::RequestResult::NOT_HANDLED: |
+ break; // Handle in the default manner. |
+ } |
+ } |
+ |
+ if (invalid_invocation) { |
+ arguments->ThrowTypeError("Invalid invocation"); |
+ return; |
} |
std::unique_ptr<base::ListValue> converted_arguments; |
v8::Local<v8::Function> callback; |
- bool conversion_success = false; |
{ |
v8::TryCatch try_catch(isolate); |
- conversion_success = signature->ParseArgumentsToJSON( |
- arguments, *type_refs_, &converted_arguments, &callback, &error); |
+ invalid_invocation = !signature->ParseArgumentsToJSON( |
+ context, argument_list, *type_refs_, |
+ &converted_arguments, &callback, &error); |
if (try_catch.HasCaught()) { |
DCHECK(!converted_arguments); |
try_catch.ReThrow(); |
return; |
} |
} |
- if (!conversion_success) { |
+ if (invalid_invocation) { |
arguments->ThrowTypeError("Invalid invocation"); |
return; |
} |