diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc index 6523b794190..f5d336ffc0a 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc @@ -4,25 +4,32 @@ #include "third_party/blink/renderer/platform/bindings/callback_interface_base.h" +#include "third_party/blink/renderer/platform/bindings/binding_security_for_platform.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" + namespace blink { CallbackInterfaceBase::CallbackInterfaceBase( v8::Local<v8::Object> callback_object, - v8::Local<v8::Context> callback_object_creation_context, SingleOperationOrNot single_op_or_not) { DCHECK(!callback_object.IsEmpty()); - DCHECK(!callback_object_creation_context.IsEmpty()); - DCHECK(callback_object->CreationContext() == - callback_object_creation_context); - - callback_relevant_script_state_ = - ScriptState::From(callback_object_creation_context); - v8::Isolate* isolate = callback_relevant_script_state_->GetIsolate(); + v8::Isolate* isolate = callback_object->GetIsolate(); callback_object_.Set(isolate, callback_object); + + incumbent_script_state_ = ScriptState::From(isolate->GetIncumbentContext()); is_callback_object_callable_ = (single_op_or_not == kSingleOperation) && callback_object->IsCallable(); - incumbent_script_state_ = ScriptState::From(isolate->GetIncumbentContext()); + + // Set |callback_relevant_script_state_| iff the creation context and the + // incumbent context are the same origin-domain. Otherwise, leave it as + // nullptr. + v8::Local<v8::Context> creation_context = callback_object->CreationContext(); + if (BindingSecurityForPlatform::ShouldAllowAccessToV8Context( + incumbent_script_state_->GetContext(), creation_context, + BindingSecurityForPlatform::ErrorReportOption::kDoNotReport)) { + callback_relevant_script_state_ = ScriptState::From(creation_context); + } } void CallbackInterfaceBase::Trace(Visitor* visitor) { @@ -31,6 +38,40 @@ void CallbackInterfaceBase::Trace(Visitor* visitor) { visitor->Trace(incumbent_script_state_); } +ScriptState* CallbackInterfaceBase::CallbackRelevantScriptStateOrReportError( + const char* interface, + const char* operation) { + if (callback_relevant_script_state_) + return callback_relevant_script_state_; + + // Report a SecurityError due to a cross origin callback object. + ScriptState::Scope incumbent_scope(incumbent_script_state_); + v8::TryCatch try_catch(GetIsolate()); + try_catch.SetVerbose(true); + ExceptionState exception_state( + GetIsolate(), ExceptionState::kExecutionContext, interface, operation); + exception_state.ThrowSecurityError( + "An invocation of the provided callback failed due to cross origin " + "access."); + return nullptr; +} + +ScriptState* CallbackInterfaceBase::CallbackRelevantScriptStateOrThrowException( + const char* interface, + const char* operation) { + if (callback_relevant_script_state_) + return callback_relevant_script_state_; + + // Throw a SecurityError due to a cross origin callback object. + ScriptState::Scope incumbent_scope(incumbent_script_state_); + ExceptionState exception_state( + GetIsolate(), ExceptionState::kExecutionContext, interface, operation); + exception_state.ThrowSecurityError( + "An invocation of the provided callback failed due to cross origin " + "access."); + return nullptr; +} + V8PersistentCallbackInterfaceBase::V8PersistentCallbackInterfaceBase( CallbackInterfaceBase* callback_interface) : callback_interface_(callback_interface) { |