void V8Window::openerAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) { LocalDOMWindow* impl = V8Window::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::SetterContext, "opener", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) { exceptionState.throwIfNeeded(); return; } // Opener can be shadowed if it is in the same domain. // Have a special handling of null value to behave // like Firefox. See bug http://b/1224887 & http://b/791706. if (value->IsNull()) { // impl->frame() cannot be null, // otherwise, SameOrigin check would have failed. ASSERT(impl->frame()); impl->frame()->loader().setOpener(0); } // Delete the accessor from this object. info.Holder()->Delete(v8AtomicString(info.GetIsolate(), "opener")); // Put property on the front (this) object. if (info.This()->IsObject()) v8::Handle<v8::Object>::Cast(info.This())->Set(v8AtomicString(info.GetIsolate(), "opener"), value); }
void V8Window::eventAttributeGetterCustom( const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); ExceptionState exceptionState(ExceptionState::GetterContext, "event", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()), impl, exceptionState)) { return; } LocalFrame* frame = impl->frame(); ASSERT(frame); // This is a fast path to retrieve info.Holder()->CreationContext(). v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(info.GetIsolate())); if (context.IsEmpty()) return; v8::Local<v8::Value> jsEvent = V8HiddenValue::getHiddenValue( ScriptState::current(info.GetIsolate()), context->Global(), V8HiddenValue::event(info.GetIsolate())); if (jsEvent.IsEmpty()) return; v8SetReturnValue(info, jsEvent); }
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); }
void InspectorRuntimeAgent::addExecutionContextToFrontend(ScriptState* scriptState, bool isPageContext, const String& origin, const String& frameId) { LocalDOMWindow* domWindow = scriptState->domWindow(); LocalFrame* frame = domWindow ? domWindow->frame() : 0; if (frame && frame->page() && frame->page()->mainFrame()) { Frame* main_frame = frame->page()->mainFrame(); Frame* jail_frame = main_frame->getDevtoolsJail(); if (jail_frame) { bool in_jail_frame = false; Frame* f = frame; while (f) { if (f == jail_frame) { in_jail_frame = true; break; } f = f->tree().parent(); } if (!in_jail_frame) return; } } int executionContextId = injectedScriptManager()->injectedScriptIdFor(scriptState); m_scriptStateToId.set(scriptState, executionContextId); DOMWrapperWorld& world = scriptState->world(); String humanReadableName = world.isIsolatedWorld() ? world.isolatedWorldHumanReadableName() : ""; m_frontend->executionContextCreated(ExecutionContextDescription::create() .setId(executionContextId) .setIsPageContext(isPageContext) .setName(humanReadableName) .setOrigin(origin) .setFrameId(frameId) .release()); }
static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data) { ASSERT(isMainThread()); // It's possible that messageHandlerInMainThread() is invoked while we're initializing a window. // In that half-baked situation, we don't have a valid context nor a valid world, // so just return immediately. if (DOMWrapperWorld::windowIsBeingInitialized()) return; v8::Isolate* isolate = v8::Isolate::GetCurrent(); // If called during context initialization, there will be no entered window. LocalDOMWindow* enteredWindow = enteredDOMWindow(isolate); if (!enteredWindow) return; String errorMessage = toCoreString(message->Get()); v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); RefPtr<ScriptCallStack> callStack = nullptr; int scriptId = message->GetScriptOrigin().ScriptID()->Value(); // Currently stack trace is only collected when inspector is open. if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) { callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); bool success = false; int topScriptId = callStack->at(0).scriptId().toInt(&success); if (success && topScriptId == scriptId) scriptId = 0; } else { Vector<ScriptCallFrame> callFrames; callStack = ScriptCallStack::create(callFrames); } v8::Handle<v8::Value> resourceName = message->GetScriptOrigin().ResourceName(); bool shouldUseDocumentURL = resourceName.IsEmpty() || !resourceName->IsString(); String resource = shouldUseDocumentURL ? enteredWindow->document()->url() : toCoreString(resourceName.As<v8::String>()); ScriptState* scriptState = ScriptState::current(isolate); RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resource, message->GetLineNumber(), message->GetStartColumn() + 1, &scriptState->world()); if (V8DOMWrapper::isDOMWrapper(data)) { v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(data); const WrapperTypeInfo* type = toWrapperTypeInfo(obj); if (V8DOMException::wrapperTypeInfo.isSubclass(type)) { DOMException* exception = V8DOMException::toNative(obj); if (exception && !exception->messageForConsole().isEmpty()) event->setUnsanitizedMessage("Uncaught " + exception->toStringForConsole()); } } // This method might be called while we're creating a new context. In this case, we // avoid storing the exception object, as we can't create a wrapper during context creation. // FIXME: Can we even get here during initialization now that we bail out when GetEntered returns an empty handle? LocalFrame* frame = enteredWindow->document()->frame(); if (frame && frame->script().existingWindowProxy(scriptState->world())) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(event.get(), data, scriptState->context()->Global(), isolate); } enteredWindow->document()->reportException(event.release(), scriptId, callStack); }
static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) { ASSERT(isMainThread()); if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { rejectedPromisesOnMainThread().handlerAdded(data); return; } ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); v8::Local<v8::Promise> promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); // There is no entered window during microtask callbacks from V8, // thus we call toDOMWindow() instead of enteredDOMWindow(). LocalDOMWindow* window = currentDOMWindow(isolate); if (!window || !window->isCurrentlyDisplayedInFrame()) return; v8::Local<v8::Value> exception = data.GetValue(); if (V8DOMWrapper::isWrapper(isolate, exception)) { // Try to get the stack & location from a wrapped exception object (e.g. DOMException). ASSERT(exception->IsObject()); v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(exception); v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(isolate, obj, V8HiddenValue::error(isolate)); if (!error.IsEmpty()) exception = error; } int scriptId = 0; int lineNumber = 0; int columnNumber = 0; String resourceName; String errorMessage; RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr; v8::Local<v8::Message> message = v8::Exception::CreateMessage(exception); if (!message.IsEmpty()) { if (v8Call(message->GetLineNumber(isolate->GetCurrentContext()), lineNumber) && v8Call(message->GetStartColumn(isolate->GetCurrentContext()), columnNumber)) ++columnNumber; resourceName = extractResourceName(message, window->document()); errorMessage = toCoreStringWithNullCheck(message->Get()); callStack = extractCallStack(isolate, message, &scriptId); } else if (!exception.IsEmpty() && exception->IsInt32()) { // For Smi's the message would be empty. errorMessage = "Uncaught " + String::number(exception.As<v8::Integer>()->Value()); } String messageForConsole = extractMessageForConsole(isolate, data.GetValue()); if (!messageForConsole.isEmpty()) errorMessage = "Uncaught " + messageForConsole; ScriptState* scriptState = ScriptState::current(isolate); rejectedPromisesOnMainThread().rejectedWithNoHandler(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack); }
static ScriptState* mainWorldScriptState(v8::Isolate* isolate, NPP npp, NPObject* npObject) { ASSERT(npObject->_class == &V8NPObjectClass); V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject); LocalDOMWindow* window = object->rootObject; if (!window || !window->isCurrentlyDisplayedInFrame()) return 0; v8::HandleScope handleScope(isolate); v8::Handle<v8::Context> context = toV8Context(object->rootObject->frame(), DOMWrapperWorld::mainWorld()); return ScriptState::from(context); }
void V8HTMLElement::HTMLConstructor( const v8::FunctionCallbackInfo<v8::Value>& info) { DCHECK(info.IsConstructCall()); v8::Isolate* isolate = info.GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); if (!RuntimeEnabledFeatures::customElementsV1Enabled() || !scriptState->world().isMainWorld()) { V8ThrowException::throwTypeError(info.GetIsolate(), "Illegal constructor"); return; } LocalDOMWindow* window = scriptState->domWindow(); ScriptCustomElementDefinition* definition = ScriptCustomElementDefinition::forConstructor( scriptState, window->customElements(), info.NewTarget()); if (!definition) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } ExceptionState exceptionState(ExceptionState::ConstructionContext, "HTMLElement", info.Holder(), isolate); Element* element; if (definition->constructionStack().isEmpty()) { // This is an element being created with 'new' from script element = definition->createElementForConstructor(*window->document()); } else { element = definition->constructionStack().last(); if (element) { // This is an element being upgraded that has called super definition->constructionStack().last().clear(); } else { // During upgrade an element has invoked the same constructor // before calling 'super' and that invocation has poached the // element. exceptionState.throwDOMException(InvalidStateError, "this instance is already constructed"); return; } } const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo(); v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper( isolate, element, wrapperType, info.Holder()); // If the element had a wrapper, we now update and return that // instead. v8SetReturnValue(info, wrapper); wrapper->SetPrototype(scriptState->context(), definition->prototype()) .ToChecked(); }
void WebDOMMessageEvent::initMessageEvent(const WebString& type, bool canBubble, bool cancelable, const WebSerializedScriptValue& messageData, const WebString& origin, const WebFrame* sourceFrame, const WebString& lastEventId, const WebMessagePortChannelArray& webChannels) { ASSERT(m_private.get()); ASSERT(isMessageEvent()); LocalDOMWindow* window = 0; if (sourceFrame) window = toWebLocalFrameImpl(sourceFrame)->frame()->domWindow(); OwnPtr<MessagePortArray> ports; if (sourceFrame) ports = MessagePort::toMessagePortArray(window->document(), webChannels); unwrap<MessageEvent>()->initMessageEvent(type, canBubble, cancelable, messageData, origin, lastEventId, window, ports.release()); }
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; }
static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) { ASSERT(isMainThread()); v8::Local<v8::Promise> promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); // There is no entered window during microtask callbacks from V8, // thus we call toDOMWindow() instead of enteredDOMWindow(). LocalDOMWindow* window = currentDOMWindow(isolate); if (!window || !window->isCurrentlyDisplayedInFrame()) return; promiseRejectHandler(data, rejectedPromisesOnMainThread(), window->document() ? window->document()->url() : String()); }
void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = V8Window::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::GetterContext, "frame", "Window", info.Holder(), info.GetIsolate()); if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->frameElement(), exceptionState)) { v8SetReturnValueNull(info); exceptionState.throwIfNeeded(); return; } // The wrapper for an <iframe> should get its prototype from the context of the frame it's in, rather than its own frame. // So, use its containing document as the creation context when wrapping. v8::Handle<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate()); RELEASE_ASSERT(!creationContext.IsEmpty()); v8::Handle<v8::Value> wrapper = toV8(impl->frameElement(), v8::Handle<v8::Object>::Cast(creationContext), info.GetIsolate()); v8SetReturnValue(info, wrapper); }
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::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(); }
PostMessageTimer(LocalDOMWindow& window, PassRefPtrWillBeRawPtr<MessageEvent> event, PassRefPtrWillBeRawPtr<LocalDOMWindow> source, SecurityOrigin* targetOrigin, PassRefPtrWillBeRawPtr<ScriptCallStack> stackTrace, UserGestureToken* userGestureToken) : SuspendableTimer(window.document()) , m_event(event) , m_window(&window) , m_targetOrigin(targetOrigin) , m_stackTrace(stackTrace) , m_userGestureToken(userGestureToken) , m_preventDestruction(false) { m_asyncOperationId = InspectorInstrumentation::traceAsyncOperationStarting(executionContext(), "postMessage"); }
static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) { ASSERT(isMainThread()); v8::Local<v8::Promise> promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); // TODO(ikilpatrick): Remove this check, extensions tests that use // extensions::ModuleSystemTest incorrectly don't have a valid script state. LocalDOMWindow* window = currentDOMWindow(isolate); if (!window || !window->isCurrentlyDisplayedInFrame()) return; // Bail out if called during context initialization. ScriptState* scriptState = ScriptState::current(isolate); if (!scriptState->contextIsValid()) return; promiseRejectHandler(data, rejectedPromisesOnMainThread(), scriptState); }
void V8Window::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* window = V8Window::toNative(info.Holder()); if (!window) return; LocalFrame* frame = window->frame(); // window is detached from a frame. if (!frame) return; // Search sub-frames. AtomicString propName = toCoreAtomicString(name); Frame* child = frame->tree().scopedChild(propName); if (child) { v8SetReturnValueFast(info, child->domWindow(), window); return; } // Search IDL functions defined in the prototype if (!info.Holder()->GetRealNamedProperty(name).IsEmpty()) return; // Search named items in the document. Document* doc = frame->document(); if (doc && doc->isHTMLDocument()) { if (toHTMLDocument(doc)->hasNamedItem(propName) || doc->hasElementWithId(propName.impl())) { RefPtrWillBeRawPtr<HTMLCollection> items = doc->windowNamedItems(propName); if (!items->isEmpty()) { if (items->hasExactlyOneItem()) { v8SetReturnValueFast(info, items->item(0), window); return; } v8SetReturnValueFast(info, items.release(), window); return; } } } }
void DevToolsHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items) { if (!event) return; ASSERT(m_frontendFrame); ScriptState* frontendScriptState = ScriptState::forMainWorld(m_frontendFrame); ScriptValue devtoolsApiObject = frontendScriptState->getFromGlobalObject("DevToolsAPI"); ASSERT(devtoolsApiObject.isObject()); Page* targetPage = m_frontendFrame->page(); if (event->target() && event->target()->executionContext() && event->target()->executionContext()->executingWindow()) { LocalDOMWindow* window = event->target()->executionContext()->executingWindow(); if (window->document() && window->document()->page()) targetPage = window->document()->page(); } RefPtrWillBeRawPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, devtoolsApiObject, items); targetPage->contextMenuController().showContextMenu(event, menuProvider); m_menuProvider = menuProvider.get(); }
void V8Window::frameElementAttributeGetterCustom( const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); if (!BindingSecurity::shouldAllowAccessTo( currentDOMWindow(info.GetIsolate()), impl->frameElement(), BindingSecurity::ErrorReportOption::DoNotReport)) { v8SetReturnValueNull(info); return; } // The wrapper for an <iframe> should get its prototype from the context of // the frame it's in, rather than its own frame. // So, use its containing document as the creation context when wrapping. v8::Local<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate()); RELEASE_ASSERT(!creationContext.IsEmpty()); v8::Local<v8::Value> wrapper = toV8(impl->frameElement(), v8::Local<v8::Object>::Cast(creationContext), info.GetIsolate()); v8SetReturnValue(info, wrapper); }
bool V8Window::namedSecurityCheckCustom(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Handle<v8::Object> window = V8Window::findInstanceInPrototypeChain(host, isolate); if (window.IsEmpty()) return false; // the frame is gone. LocalDOMWindow* targetWindow = V8Window::toNative(window); ASSERT(targetWindow); LocalFrame* target = targetWindow->frame(); if (!target) return false; // Notify the loader's client if the initial document has been accessed. if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument()) target->loader().didAccessInitialDocument(); if (key->IsString()) { DEFINE_STATIC_LOCAL(const AtomicString, nameOfProtoProperty, ("__proto__", AtomicString::ConstructFromLiteral)); AtomicString name = toCoreAtomicString(key.As<v8::String>()); Frame* childFrame = target->tree().scopedChild(name); // Notice that we can't call HasRealNamedProperty for ACCESS_HAS // because that would generate infinite recursion. if (type == v8::ACCESS_HAS && childFrame) return true; // We need to explicitly compare against nameOfProtoProperty because // V8's JSObject::LocalLookup finds __proto__ before // interceptors and even when __proto__ isn't a "real named property". v8::Handle<v8::String> keyString = key.As<v8::String>(); if (type == v8::ACCESS_GET && childFrame && !host->HasRealNamedProperty(keyString) && !window->HasRealNamedProperty(keyString) && name != nameOfProtoProperty) return true; }
void DOMWindowFileSystem::webkitRequestFileSystem(LocalDOMWindow& window, int type, long long size, PassOwnPtr<FileSystemCallback> successCallback, PassOwnPtr<ErrorCallback> errorCallback) { if (!window.isCurrentlyDisplayedInFrame()) return; Document* document = window.document(); if (!document) return; if (!document->securityOrigin()->canAccessFileSystem()) { DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::SECURITY_ERR)); return; } FileSystemType fileSystemType = static_cast<FileSystemType>(type); if (!DOMFileSystemBase::isValidType(fileSystemType)) { DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::INVALID_MODIFICATION_ERR)); return; } LocalFileSystem::from(*document)->requestFileSystem(document, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, document, fileSystemType)); }
void LocalFrame::sendOrientationChangeEvent() { if (!RuntimeEnabledFeatures::orientationEventEnabled() && !RuntimeEnabledFeatures::screenOrientationEnabled()) return; if (page()->visibilityState() != PageVisibilityStateVisible) return; LocalDOMWindow* window = domWindow(); if (!window) return; window->dispatchEvent(Event::create(EventTypeNames::orientationchange)); // Notify subframes. Vector<RefPtr<LocalFrame> > childFrames; for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling()) { if (child->isLocalFrame()) childFrames.append(toLocalFrame(child)); } for (size_t i = 0; i < childFrames.size(); ++i) childFrames[i]->sendOrientationChangeEvent(); }
void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(LocalDOMWindow& window, const String& url, PassOwnPtr<EntryCallback> successCallback, PassOwnPtr<ErrorCallback> errorCallback) { if (!window.isCurrentlyDisplayedInFrame()) return; Document* document = window.document(); if (!document) return; SecurityOrigin* securityOrigin = document->securityOrigin(); KURL completedURL = document->completeURL(url); if (!securityOrigin->canAccessFileSystem() || !securityOrigin->canRequest(completedURL)) { DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::SECURITY_ERR)); return; } if (!completedURL.isValid()) { DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(FileError::ENCODING_ERR)); return; } LocalFileSystem::from(*document)->resolveURL(document, completedURL, ResolveURICallbacks::create(successCallback, errorCallback, document)); }
void V8Window::frameElementAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder())); ExceptionState exceptionState(ExceptionState::GetterContext, "frame", "Window", info.Holder(), info.GetIsolate()); // Do the security check against the parent frame rather than // frameElement() itself, so that a remote parent frame can be handled // properly. In that case, there's no frameElement(), yet we should still // throw a proper exception and deny access. Frame* target = impl->frame() ? impl->frame()->tree().parent() : nullptr; if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), target, exceptionState)) { v8SetReturnValueNull(info); exceptionState.throwIfNeeded(); return; } // The wrapper for an <iframe> should get its prototype from the context of the frame it's in, rather than its own frame. // So, use its containing document as the creation context when wrapping. v8::Local<v8::Value> creationContext = toV8(&impl->frameElement()->document(), info.Holder(), info.GetIsolate()); RELEASE_ASSERT(!creationContext.IsEmpty()); v8::Local<v8::Value> wrapper = toV8(impl->frameElement(), v8::Local<v8::Object>::Cast(creationContext), info.GetIsolate()); v8SetReturnValue(info, wrapper); }
static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local<v8::Value> data) { ASSERT(isMainThread()); v8::Isolate* isolate = v8::Isolate::GetCurrent(); // If called during context initialization, there will be no entered window. LocalDOMWindow* enteredWindow = enteredDOMWindow(isolate); if (!enteredWindow || !enteredWindow->isCurrentlyDisplayedInFrame()) return; int scriptId = 0; RefPtrWillBeRawPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scriptId); String resourceName = extractResourceName(message, enteredWindow->document()); AccessControlStatus accessControlStatus = NotSharableCrossOrigin; if (message->IsOpaque()) accessControlStatus = OpaqueResource; else if (message->IsSharedCrossOrigin()) accessControlStatus = SharableCrossOrigin; ScriptState* scriptState = ScriptState::current(isolate); String errorMessage = toCoreStringWithNullCheck(message->Get()); int lineNumber = 0; int columnNumber = 0; if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)) ++columnNumber; RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, resourceName, lineNumber, columnNumber, &scriptState->world()); String messageForConsole = extractMessageForConsole(isolate, data); if (!messageForConsole.isEmpty()) event->setUnsanitizedMessage("Uncaught " + messageForConsole); // This method might be called while we're creating a new context. In this case, we // avoid storing the exception object, as we can't create a wrapper during context creation. // FIXME: Can we even get here during initialization now that we bail out when GetEntered returns an empty handle? LocalFrame* frame = enteredWindow->document()->frame(); if (frame && frame->script().existingWindowProxy(scriptState->world())) { V8ErrorHandler::storeExceptionOnErrorEventWrapper(isolate, event.get(), data, scriptState->context()->Global()); } if (scriptState->world().isPrivateScriptIsolatedWorld()) { // We allow a private script to dispatch error events even in a EventDispatchForbiddenScope scope. // Without having this ability, it's hard to debug the private script because syntax errors // in the private script are not reported to console (the private script just crashes silently). // Allowing error events in private scripts is safe because error events don't propagate to // other isolated worlds (which means that the error events won't fire any event listeners // in user's scripts). EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; enteredWindow->document()->reportException(event.release(), scriptId, callStack, accessControlStatus); } else { enteredWindow->document()->reportException(event.release(), scriptId, callStack, accessControlStatus); } }
DOMWindowIndexedDatabase::DOMWindowIndexedDatabase(LocalDOMWindow& window) : DOMWindowProperty(window.frame()) , m_window(window) { }
WindowAnimationWorklet::WindowAnimationWorklet(LocalDOMWindow& window) : DOMWindowProperty(window.frame()) {}
DOMWindowCrypto::DOMWindowCrypto(LocalDOMWindow& window) : DOMWindowProperty(window.frame()) { }
DOMWindowWebCL::DOMWindowWebCL(LocalDOMWindow& window) : DOMWindowProperty(window.frame()) , m_window(window) { }
// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors void V8HTMLConstructor::htmlConstructor( const v8::FunctionCallbackInfo<v8::Value>& info, const WrapperTypeInfo& wrapperTypeInfo, const HTMLElementType elementInterfaceName) { TRACE_EVENT0("blink", "HTMLConstructor"); DCHECK(info.IsConstructCall()); v8::Isolate* isolate = info.GetIsolate(); ScriptState* scriptState = ScriptState::current(isolate); v8::Local<v8::Value> newTarget = info.NewTarget(); if (!scriptState->contextIsValid()) { V8ThrowException::throwError(isolate, "The context has been destroyed"); return; } if (!RuntimeEnabledFeatures::customElementsV1Enabled() || !scriptState->world().isMainWorld()) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } // 2. If NewTarget is equal to the active function object, then // throw a TypeError and abort these steps. v8::Local<v8::Function> activeFunctionObject = scriptState->perContextData()->constructorForType( &V8HTMLElement::wrapperTypeInfo); if (newTarget == activeFunctionObject) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } LocalDOMWindow* window = scriptState->domWindow(); CustomElementRegistry* registry = window->customElements(); // 3. Let definition be the entry in registry with constructor equal to // NewTarget. // If there is no such definition, then throw a TypeError and abort these // steps. ScriptCustomElementDefinition* definition = ScriptCustomElementDefinition::forConstructor(scriptState, registry, newTarget); if (!definition) { V8ThrowException::throwTypeError(isolate, "Illegal constructor"); return; } const AtomicString& localName = definition->descriptor().localName(); const AtomicString& name = definition->descriptor().name(); if (localName == name) { // Autonomous custom element // 4.1. If the active function object is not HTMLElement, then throw a // TypeError if (!V8HTMLElement::wrapperTypeInfo.equals(&wrapperTypeInfo)) { V8ThrowException::throwTypeError(isolate, "Illegal constructor: autonomous custom " "elements must extend HTMLElement"); return; } } else { // Customized built-in element // 5. If local name is not valid for interface, throw TypeError if (htmlElementTypeForTag(localName) != elementInterfaceName) { V8ThrowException::throwTypeError(isolate, "Illegal constructor: localName does " "not match the HTML element interface"); return; } } ExceptionState exceptionState(isolate, ExceptionState::ConstructionContext, "HTMLElement"); v8::TryCatch tryCatch(isolate); // 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions. v8::Local<v8::Value> prototype; v8::Local<v8::String> prototypeString = v8AtomicString(isolate, "prototype"); if (!v8Call(newTarget.As<v8::Object>()->Get(scriptState->context(), prototypeString), prototype)) { return; } // 7. If Type(prototype) is not Object, then: ... if (!prototype->IsObject()) { if (V8PerContextData* perContextData = V8PerContextData::from( newTarget.As<v8::Object>()->CreationContext())) { prototype = perContextData->prototypeForType(&V8HTMLElement::wrapperTypeInfo); } else { V8ThrowException::throwError(isolate, "The context has been destroyed"); return; } } // 8. If definition's construction stack is empty... Element* element; if (definition->constructionStack().isEmpty()) { // This is an element being created with 'new' from script element = definition->createElementForConstructor(*window->document()); } else { element = definition->constructionStack().last(); if (element) { // This is an element being upgraded that has called super definition->constructionStack().last().clear(); } else { // During upgrade an element has invoked the same constructor // before calling 'super' and that invocation has poached the // element. exceptionState.throwDOMException(InvalidStateError, "this instance is already constructed"); return; } } const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo(); v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper( isolate, element, wrapperType, info.Holder()); // If the element had a wrapper, we now update and return that // instead. v8SetReturnValue(info, wrapper); // 11. Perform element.[[SetPrototypeOf]](prototype). Rethrow any exceptions. // Note: I don't think this prototype set *can* throw exceptions. wrapper->SetPrototype(scriptState->context(), prototype.As<v8::Object>()) .ToChecked(); }