summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc
diff options
context:
space:
mode:
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.cc59
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) {