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);
}
Exemple #2
0
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());
}
Exemple #5
0
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);
}
Exemple #7
0
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");
 }
Exemple #16
0
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;
            }
        }
    }
}
Exemple #18
0
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();
}
Exemple #19
0
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));
}
Exemple #22
0
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);
}
Exemple #25
0
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)
{
}
Exemple #30
0
// 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();
}