static void hrefCallWithAttributeSetter(v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info) { v8::Handle<v8::Object> holder = info.Holder(); TestNode* impl = V8TestNode::toImpl(holder); TOSTRING_VOID(V8StringResource<>, cppValue, v8Value); ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate()); impl->setHrefCallWith(executionContext, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), cppValue); }
void V8WrapperInstantiationScope::convertException() { v8::Isolate* isolate = m_context->GetIsolate(); // TODO(jochen): Currently, Location is the only object for which we can reach this code path. Should be generalized. ExceptionState exceptionState(ExceptionState::ConstructionContext, "Location", isolate->GetCurrentContext()->Global(), isolate); LocalDOMWindow* callingWindow = callingDOMWindow(isolate); DOMWindow* targetWindow = toDOMWindow(m_context); exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAccessErrorMessage(callingWindow), targetWindow->crossDomainAccessErrorMessage(callingWindow)); exceptionState.throwIfNeeded(); }
static bool canAccessDocument(v8::Isolate* isolate, Document* targetDocument, ExceptionState& exceptionState) { DOMWindow* callingWindow = callingDOMWindow(isolate); if (isDocumentAccessibleFromDOMWindow(targetDocument, callingWindow)) return true; if (targetDocument->domWindow()) exceptionState.throwSecurityError(targetDocument->domWindow()->sanitizedCrossDomainAccessErrorMessage(callingWindow), targetDocument->domWindow()->crossDomainAccessErrorMessage(callingWindow)); return false; }
static void hrefCallWithAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Local<v8::Object> holder = info.Holder(); TestNode* impl = V8TestNode::toImpl(holder); V8StringResource<> cppValue = v8Value; if (!cppValue.prepare()) return; ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate()); impl->setHrefCallWith(executionContext, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), cppValue); }
void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate()); if (UNLIKELY(info.Length() < 2)) { setMinimumArityTypeError(exceptionState, 2, info.Length()); exceptionState.throwIfNeeded(); return; } // None of these need to be RefPtr because info and context are guaranteed // to hold on to them. DOMWindow* window = V8Window::toImpl(info.Holder()); LocalDOMWindow* source = callingDOMWindow(info.GetIsolate()); ASSERT(window); UseCounter::countIfNotPrivateScript(info.GetIsolate(), window->frame(), UseCounter::WindowPostMessage); // If called directly by WebCore we don't have a calling context. if (!source) { exceptionState.throwTypeError("No active calling context exists."); exceptionState.throwIfNeeded(); return; } // This function has variable arguments and can be: // Per current spec: // postMessage(message, targetOrigin) // postMessage(message, targetOrigin, {sequence of transferrables}) // Legacy non-standard implementations in webkit allowed: // postMessage(message, {sequence of transferrables}, targetOrigin); OwnPtrWillBeRawPtr<MessagePortArray> portArray = adoptPtrWillBeNoop(new MessagePortArray); ArrayBufferArray arrayBufferArray; int targetOriginArgIndex = 1; if (info.Length() > 2) { int transferablesArgIndex = 2; if (isLegacyTargetOriginDesignation(info[2])) { UseCounter::countIfNotPrivateScript(info.GetIsolate(), window->frame(), UseCounter::WindowPostMessageWithLegacyTargetOriginArgument); targetOriginArgIndex = 2; transferablesArgIndex = 1; } if (!SerializedScriptValue::extractTransferables(info.GetIsolate(), info[transferablesArgIndex], transferablesArgIndex, *portArray, arrayBufferArray, exceptionState)) { exceptionState.throwIfNeeded(); return; } } TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, targetOrigin, info[targetOriginArgIndex]); RefPtr<SerializedScriptValue> message = SerializedScriptValueFactory::instance().create(info.GetIsolate(), info[0], portArray.get(), &arrayBufferArray, exceptionState); if (exceptionState.throwIfNeeded()) return; window->postMessage(message.release(), portArray.get(), targetOrigin, source, exceptionState); exceptionState.throwIfNeeded(); }
static bool canAccessDocument(v8::Isolate* isolate, Document* targetDocument, SecurityReportingOption reportingOption = ReportSecurityError) { DOMWindow* callingWindow = callingDOMWindow(isolate); if (isDocumentAccessibleFromDOMWindow(targetDocument, callingWindow)) return true; if (reportingOption == ReportSecurityError && targetDocument->domWindow()) { if (Frame* frame = targetDocument->frame()) frame->domWindow()->printErrorMessage(targetDocument->domWindow()->crossDomainAccessErrorMessage(callingWindow)); } return false; }
static bool canAccessFrame(v8::Isolate* isolate, SecurityOrigin* targetFrameOrigin, DOMWindow* targetWindow, SecurityReportingOption reportingOption = ReportSecurityError) { LocalDOMWindow* callingWindow = callingDOMWindow(isolate); // It's important to check that targetWindow is a LocalDOMWindow: it's // possible for a remote frame and local frame to have the same security // origin, depending on the model being used to allocate Frames between // processes. See https://crbug.com/601629. if (targetWindow->isLocalDOMWindow() && isOriginAccessibleFromDOMWindow(targetFrameOrigin, callingWindow)) return true; if (reportingOption == ReportSecurityError && targetWindow) callingWindow->printErrorMessage(targetWindow->crossDomainAccessErrorMessage(callingWindow)); return false; }
void V8WrapperInstantiationScope::securityCheck(v8::Isolate* isolate, v8::Local<v8::Context> contextForWrapper) { if (m_context.IsEmpty()) return; // If the context is different, we need to make sure that the current // context has access to the creation context. Frame* frame = toFrameIfNotDetached(contextForWrapper); if (!frame) return; const DOMWrapperWorld& currentWorld = DOMWrapperWorld::world(m_context); RELEASE_ASSERT(currentWorld.worldId() == DOMWrapperWorld::world(contextForWrapper).worldId()); if (currentWorld.isMainWorld()) { RELEASE_ASSERT(BindingSecurity::shouldAllowAccessToFrame(isolate, callingDOMWindow(isolate), frame, DoNotReportSecurityError)); } }
void V8Window::showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = V8Window::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::ExecutionContext, "showModalDialog", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) { exceptionState.throwIfNeeded(); return; } TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, urlString, info[0]); DialogHandler handler(info[1], ScriptState::current(info.GetIsolate())); TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, dialogFeaturesString, info[2]); impl->showModalDialog(urlString, dialogFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), setUpDialog, &handler); v8SetReturnValue(info, handler.returnValue()); }
void V8Window::showModalDialogMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { DOMWindow* impl = V8Window::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::ExecutionContext, "showModalDialog", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) { exceptionState.throwIfNeeded(); return; } V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, urlString, info[0]); DialogHandler handler(info[1]); V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, dialogFeaturesString, info[2]); impl->showModalDialog(urlString, dialogFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate()), setUpDialog, &handler); v8SetReturnValue(info, handler.returnValue(info.GetIsolate())); }
void V8Window::postMessageMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { // None of these need to be RefPtr because info and context are guaranteed // to hold on to them. LocalDOMWindow* window = V8Window::toNative(info.Holder()); LocalDOMWindow* source = callingDOMWindow(info.GetIsolate()); ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate()); // If called directly by WebCore we don't have a calling context. if (!source) { exceptionState.throwTypeError("No active calling context exists."); exceptionState.throwIfNeeded(); return; } // This function has variable arguments and can be: // Per current spec: // postMessage(message, targetOrigin) // postMessage(message, targetOrigin, {sequence of transferrables}) // Legacy non-standard implementations in webkit allowed: // postMessage(message, {sequence of transferrables}, targetOrigin); MessagePortArray portArray; ArrayBufferArray arrayBufferArray; int targetOriginArgIndex = 1; if (info.Length() > 2) { int transferablesArgIndex = 2; if (isLegacyTargetOriginDesignation(info[2])) { targetOriginArgIndex = 2; transferablesArgIndex = 1; } if (!SerializedScriptValue::extractTransferables(info[transferablesArgIndex], transferablesArgIndex, portArray, arrayBufferArray, exceptionState, info.GetIsolate())) { exceptionState.throwIfNeeded(); return; } } TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, targetOrigin, info[targetOriginArgIndex]); RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, exceptionState, info.GetIsolate()); if (exceptionState.throwIfNeeded()) return; window->postMessage(message.release(), &portArray, targetOrigin, source, exceptionState); exceptionState.throwIfNeeded(); }
void V8HTMLDocument::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { HTMLDocument* htmlDocument = V8HTMLDocument::toNative(info.Holder()); if (info.Length() > 2) { if (RefPtr<LocalFrame> frame = htmlDocument->frame()) { // Fetch the global object for the frame. v8::Local<v8::Context> context = toV8Context(info.GetIsolate(), frame.get(), DOMWrapperWorld::current(info.GetIsolate())); // Bail out if we cannot get the context. if (context.IsEmpty()) return; v8::Local<v8::Object> global = context->Global(); // Get the open property of the global object. v8::Local<v8::Value> function = global->Get(v8AtomicString(info.GetIsolate(), "open")); // Failed; return without throwing (new) exception. if (function.IsEmpty()) return; // If the open property is not a function throw a type error. if (!function->IsFunction()) { throwTypeError("open is not a function", info.GetIsolate()); return; } // Wrap up the arguments and call the function. OwnPtr<v8::Local<v8::Value>[]> params = adoptArrayPtr(new v8::Local<v8::Value>[info.Length()]); for (int i = 0; i < info.Length(); i++) params[i] = info[i]; v8SetReturnValue(info, frame->script().callFunction(v8::Local<v8::Function>::Cast(function), global, info.Length(), params.get())); return; } } ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Document", info.Holder(), info.GetIsolate()); htmlDocument->open(callingDOMWindow(info.GetIsolate())->document(), exceptionState); if (exceptionState.throwIfNeeded()) return; v8SetReturnValue(info, info.Holder()); }
void V8EventTarget::addEventListenerMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { ExceptionState exceptionState(ExceptionState::ExecutionContext, "addEventListener", "EventTarget", info.Holder(), info.GetIsolate()); if (UNLIKELY(info.Length() < 2)) { setMinimumArityTypeError(exceptionState, 2, info.Length()); exceptionState.throwIfNeeded(); return; } EventTarget* impl = V8EventTarget::toImpl(info.Holder()); if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) { exceptionState.throwIfNeeded(); return; } V8StringResource<> type; RefPtrWillBeRawPtr<EventListener> listener; EventListenerOptionsOrBoolean options; { type = info[0]; if (!type.prepare()) return; listener = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[1], false, ListenerFindOrCreate); // TODO(dtapuska): This custom binding code can be eliminated once // EventListenerOptions runtime enabled feature is removed. // http://crbug.com/545163 if (UNLIKELY(info.Length() <= 2) || isUndefinedOrNull(info[2])) { addEventListenerMethodPrologueCustom(info, impl); impl->addEventListener(type, listener); addEventListenerMethodEpilogueCustom(info, impl); return; } V8EventListenerOptionsOrBoolean::toImpl(info.GetIsolate(), info[2], options, UnionTypeConversionMode::NotNullable, exceptionState); if (exceptionState.throwIfNeeded()) return; } addEventListenerMethodPrologueCustom(info, impl); impl->addEventListener(type, listener, options); addEventListenerMethodEpilogueCustom(info, impl); }
AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { v8::Handle<v8::Function> lookupNamespaceURIFunc; v8::Handle<v8::String> lookupNamespaceURIName = v8AtomicString(m_isolate, "lookupNamespaceURI"); // Check if the resolver has a function property named lookupNamespaceURI. if (m_resolver->Has(lookupNamespaceURIName)) { v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get(lookupNamespaceURIName); if (lookupNamespaceURI->IsFunction()) lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast(lookupNamespaceURI); } if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) { LocalFrame* frame = callingDOMWindow(m_isolate)->frame(); if (frame && frame->host()) frame->host()->console().addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method."); return nullAtom; } // Catch exceptions from calling the namespace resolver. v8::TryCatch tryCatch; tryCatch.SetVerbose(true); // Print exceptions to console. const int argc = 1; v8::Handle<v8::Value> argv[argc] = { v8String(m_isolate, prefix) }; v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc; v8::Handle<v8::Value> retval = ScriptController::callFunction(callingExecutionContext(m_isolate), function, m_resolver, argc, argv, m_isolate); // Eat exceptions from namespace resolver and return an empty string. This will most likely cause NamespaceError. if (tryCatch.HasCaught()) return nullAtom; V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, returnString, retval, nullAtom); return returnString; }
void V8Window::openMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = V8Window::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) { exceptionState.throwIfNeeded(); return; } TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, urlString, info[0]); AtomicString frameName; if (info[1]->IsUndefined() || info[1]->IsNull()) { frameName = "_blank"; } else { TOSTRING_VOID(V8StringResource<>, frameNameResource, info[1]); frameName = frameNameResource; } TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>, windowFeaturesString, info[2]); RefPtrWillBeRawPtr<LocalDOMWindow> openedWindow = impl->open(urlString, frameName, windowFeaturesString, callingDOMWindow(info.GetIsolate()), enteredDOMWindow(info.GetIsolate())); if (!openedWindow) return; v8SetReturnValueFast(info, openedWindow.release(), impl); }
static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); Frame* target = findFrame(isolate, host, data); if (!target) return; DOMWindow* targetWindow = target->domWindow(); // FIXME: We should modify V8 to pass in more contextual information (context, property, and object). ExceptionState exceptionState(ExceptionState::UnknownContext, 0, 0, isolate->GetCurrentContext()->Global(), isolate); exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAccessErrorMessage(callingDOMWindow(isolate)), targetWindow->crossDomainAccessErrorMessage(callingDOMWindow(isolate))); exceptionState.throwIfNeeded(); }