Beispiel #1
0
static v8::Handle<v8::Value> handlePostMessageCallback(const v8::Arguments& args)
{
    DOMWindow* window = V8DOMWindow::toNative(args.Holder());

    DOMWindow* source = V8Proxy::retrieveFrameForCallingContext()->domWindow();
    ASSERT(source->frame());

    bool didThrow = false;
    RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(args[0], didThrow);
    if (didThrow)
        return v8::Undefined();

    MessagePortArray portArray;
    String targetOrigin;

    // This function has variable arguments and can either be:
    //   postMessage(message, port, targetOrigin);
    // or
    //   postMessage(message, targetOrigin);
    v8::TryCatch tryCatch;
    if (args.Length() > 2) {
        if (!getMessagePortArray(args[1], portArray))
            return v8::Undefined();
        targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
    } else {
        targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
    }

    if (tryCatch.HasCaught())
        return v8::Undefined();

    ExceptionCode ec = 0;
    window->postMessage(message.release(), &portArray, targetOrigin, source, ec);
    return throwError(ec);
}
JSValue JSDOMWindow::postMessage(ExecState* exec)
{
    DOMWindow* window = impl();

    DOMWindow* source = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
    PassRefPtr<SerializedScriptValue> message = SerializedScriptValue::create(exec, exec->argument(0));

    if (exec->hadException())
        return jsUndefined();

    MessagePortArray messagePorts;
    if (exec->argumentCount() > 2)
        fillMessagePortArray(exec, exec->argument(1), messagePorts);
    if (exec->hadException())
        return jsUndefined();

    String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, exec->argument((exec->argumentCount() == 2) ? 1 : 2));
    if (exec->hadException())
        return jsUndefined();

    ExceptionCode ec = 0;
    window->postMessage(message, &messagePorts, targetOrigin, source, ec);
    setDOMException(exec, ec);

    return jsUndefined();
}
Beispiel #3
0
void V8Window::postMessageMethodCustom(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage",
                                "Window", info.Holder(), info.GetIsolate());
  if (UNLIKELY(info.Length() < 2)) {
    exceptionState.throwTypeError(
        ExceptionMessages::notEnoughArguments(2, info.Length()));
    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());
  // TODO(yukishiino): The HTML spec specifies that we should use the
  // Incumbent Realm instead of the Current Realm, but currently we don't have
  // a way to retrieve the Incumbent Realm.  See also:
  // https://html.spec.whatwg.org/multipage/comms.html#dom-window-postmessage
  LocalDOMWindow* source = currentDOMWindow(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.");
    return;
  }

  // This function has variable arguments and can be:
  //   postMessage(message, targetOrigin)
  //   postMessage(message, targetOrigin, {sequence of transferrables})
  // TODO(foolip): Type checking of the arguments should happen in order, so
  // that e.g. postMessage({}, { toString: () => { throw Error(); } }, 0)
  // throws the Error from toString, not the TypeError for argument 3.
  Transferables transferables;
  const int targetOriginArgIndex = 1;
  if (info.Length() > 2) {
    const int transferablesArgIndex = 2;
    if (!SerializedScriptValue::extractTransferables(
            info.GetIsolate(), info[transferablesArgIndex],
            transferablesArgIndex, transferables, exceptionState)) {
      return;
    }
  }
  // TODO(foolip): targetOrigin should be a USVString in IDL and treated as
  // such here, without TreatNullAndUndefinedAsNullString.
  TOSTRING_VOID(V8StringResource<TreatNullAndUndefinedAsNullString>,
                targetOrigin, info[targetOriginArgIndex]);

  RefPtr<SerializedScriptValue> message = SerializedScriptValue::serialize(
      info.GetIsolate(), info[0], &transferables, nullptr, exceptionState);
  if (exceptionState.hadException())
    return;

  window->postMessage(message.release(), transferables.messagePorts,
                      targetOrigin, source, exceptionState);
}
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();
}
Beispiel #5
0
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.
    DOMWindow* window = V8Window::toNative(info.Holder());
    DOMWindow* source = activeDOMWindow();

    // If called directly by WebCore we don't have a calling context.
    if (!source) {
        throwUninformativeAndGenericTypeError(info.GetIsolate());
        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;
        }
        bool notASequence = false;
        if (!extractTransferables(info[transferablesArgIndex], portArray, arrayBufferArray, notASequence, info.GetIsolate())) {
            if (notASequence)
                throwTypeError(ExceptionMessages::failedToExecute("postMessage", "Window", ExceptionMessages::notAnArrayTypeArgumentOrValue(transferablesArgIndex + 1)), info.GetIsolate());
            return;
        }
    }
    V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<WithUndefinedOrNullCheck>, targetOrigin, info[targetOriginArgIndex]);

    bool didThrow = false;
    RefPtr<SerializedScriptValue> message =
        SerializedScriptValue::create(info[0], &portArray, &arrayBufferArray, didThrow, info.GetIsolate());
    if (didThrow)
        return;

    ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", "Window", info.Holder(), info.GetIsolate());
    window->postMessage(message.release(), &portArray, targetOrigin, source, exceptionState);
    exceptionState.throwIfNeeded();
}
Beispiel #6
0
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.
    DOMWindow* window = V8Window::toNative(info.Holder());
    DOMWindow* 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<WithUndefinedOrNullCheck>, 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();
}
JSValue JSDOMWindow::postMessage(ExecState* exec, const ArgList& args)
{
    DOMWindow* window = impl();

    DOMWindow* source = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
    String message = args.at(0).toString(exec);

    if (exec->hadException())
        return jsUndefined();

    MessagePort* messagePort = (args.size() == 2) ? 0 : toMessagePort(args.at(1));

    String targetOrigin = valueToStringWithUndefinedOrNullCheck(exec, args.at((args.size() == 2) ? 1 : 2));
    if (exec->hadException())
        return jsUndefined();

    ExceptionCode ec = 0;
    window->postMessage(message, messagePort, targetOrigin, source, ec);
    setDOMException(exec, ec);

    return jsUndefined();
}
Beispiel #8
0
static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (UNLIKELY(state.argumentCount() < 2))
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    Vector<RefPtr<MessagePort>> messagePorts;
    Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;

    // 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);
    int targetOriginArgIndex = 1;
    if (state.argumentCount() > 2) {
        int transferablesArgIndex = 2;
        if (state.uncheckedArgument(2).isString()) {
            targetOriginArgIndex = 2;
            transferablesArgIndex = 1;
        }
        extractTransferables(state, state.argument(transferablesArgIndex), messagePorts, arrayBuffers);
    }
    RETURN_IF_EXCEPTION(scope, JSValue());

    auto message = SerializedScriptValue::create(state, state.uncheckedArgument(0), messagePorts, WTFMove(arrayBuffers));
    RETURN_IF_EXCEPTION(scope, JSValue());

    String targetOrigin = convert<IDLNullable<IDLUSVString>>(state, state.uncheckedArgument(targetOriginArgIndex));
    RETURN_IF_EXCEPTION(scope, JSValue());

    propagateException(state, scope, impl.postMessage(message.releaseNonNull(), WTFMove(messagePorts), targetOrigin, callerDOMWindow(&state)));

    return jsUndefined();
}