Пример #1
0
ScriptPromise SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& es)
{
    WebKit::WebCryptoKeyFormat format;
    if (!Key::parseFormat(rawFormat, format, es))
        return ScriptPromise();

    if (!keyData) {
        es.throwTypeError("Invalid keyData argument");
        return ScriptPromise();
    }

    WebKit::WebCryptoKeyUsageMask keyUsages;
    if (!Key::parseUsageMask(rawKeyUsages, keyUsages, es))
        return ScriptPromise();

    WebKit::WebCryptoAlgorithm algorithm;
    if (!normalizeAlgorithm(rawAlgorithm, ImportKey, algorithm, es))
        return ScriptPromise();

    const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->baseAddress());

    RefPtr<CryptoResult> result = CryptoResult::create();
    WebKit::Platform::current()->crypto()->importKey(format, keyDataBytes, keyData->byteLength(), algorithm, extractable, keyUsages, result->result());
    return result->promise();
}
Пример #2
0
ScriptPromise ScriptPromise::then(PassOwnPtr<ScriptFunction> onFulfilled, PassOwnPtr<ScriptFunction> onRejected)
{
    if (m_promise.isEmpty())
        return ScriptPromise();

    v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();
    v8::Local<v8::Function> v8OnFulfilled = ScriptFunction::adoptByGarbageCollector(onFulfilled);
    v8::Local<v8::Function> v8OnRejected = ScriptFunction::adoptByGarbageCollector(onRejected);

    if (V8PromiseCustom::isPromise(promise, m_scriptState->isolate()))
        return ScriptPromise(m_scriptState.get(), V8PromiseCustom::then(promise, v8OnFulfilled, v8OnRejected, m_scriptState->isolate()));

    ASSERT(promise->IsPromise());
    // Return this Promise if no handlers are given.
    // In fact it is not the exact bahavior of Promise.prototype.then
    // but that is not a problem in this case.
    v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>();
    // FIXME: Use Then once it is introduced.
    if (!v8OnFulfilled.IsEmpty()) {
        resultPromise = resultPromise->Chain(v8OnFulfilled);
        if (resultPromise.IsEmpty()) {
            // v8::Promise::Chain may return an empty value, for example when
            // the stack is exhausted.
            return ScriptPromise();
        }
    }
    if (!v8OnRejected.IsEmpty())
        resultPromise = resultPromise->Catch(v8OnRejected);

    return ScriptPromise(m_scriptState.get(), resultPromise);
}
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLImageElement* image, int sx, int sy, int sw, int sh, ExceptionState& exceptionState)
{
    // This variant does not work in worker threads.
    ASSERT(eventTarget.toDOMWindow());

    if (!image->cachedImage()) {
        exceptionState.throwDOMException(InvalidStateError, "No image can be retrieved from the provided element.");
        return ScriptPromise();
    }
    if (image->cachedImage()->image()->isSVGImage()) {
        exceptionState.throwDOMException(InvalidStateError, "The image element contains an SVG image, which is unsupported.");
        return ScriptPromise();
    }
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
        return ScriptPromise();
    }
    if (!image->cachedImage()->image()->currentFrameHasSingleSecurityOrigin()) {
        exceptionState.throwSecurityError("The source image contains image data from multiple origins.");
        return ScriptPromise();
    }
    Document* document = eventTarget.toDOMWindow()->document();
    if (!image->cachedImage()->passesAccessControlCheck(document->securityOrigin()) && document->securityOrigin()->taintsCanvas(image->src())) {
        exceptionState.throwSecurityError("Cross-origin access to the source image is denied.");
        return ScriptPromise();
    }
    // FIXME: make ImageBitmap creation asynchronous crbug.com/258082
    return fulfillImageBitmap(scriptState, ImageBitmap::create(image, IntRect(sx, sy, sw, sh)));
}
Пример #4
0
ScriptPromise ScriptPromise::then(PassOwnPtr<ScriptFunction> onFulfilled, PassOwnPtr<ScriptFunction> onRejected)
{
    if (m_promise.hasNoValue() || !m_promise.isObject())
        return ScriptPromise();
    v8::Handle<v8::Object> promise = m_promise.v8Value().As<v8::Object>();
    return ScriptPromise(V8PromiseCustom::then(promise, adoptByGarbageCollector(onFulfilled), adoptByGarbageCollector(onRejected), isolate()), isolate());
}
Пример #5
0
ScriptPromise ScriptPromise::then(v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejected)
{
    if (m_promise.isEmpty())
        return ScriptPromise();

    v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();

    ASSERT(promise->IsPromise());
    // Return this Promise if no handlers are given.
    // In fact it is not the exact bahavior of Promise.prototype.then
    // but that is not a problem in this case.
    v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>();
    if (!onFulfilled.IsEmpty()) {
        resultPromise = resultPromise->Then(onFulfilled);
        if (resultPromise.IsEmpty()) {
            // v8::Promise::Then may return an empty value, for example when
            // the stack is exhausted.
            return ScriptPromise();
        }
    }
    if (!onRejected.IsEmpty())
        resultPromise = resultPromise->Catch(onRejected);

    return ScriptPromise(m_scriptState.get(), resultPromise);
}
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLVideoElement* video, int sx, int sy, int sw, int sh, ExceptionState& exceptionState)
{
    // This variant does not work in worker threads.
    ASSERT(eventTarget.toDOMWindow());

    if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) {
        exceptionState.throwDOMException(InvalidStateError, "The provided element has not retrieved data.");
        return ScriptPromise();
    }
    if (video->readyState() <= HTMLMediaElement::HAVE_METADATA) {
        exceptionState.throwDOMException(InvalidStateError, "The provided element's player has no current data.");
        return ScriptPromise();
    }
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
        return ScriptPromise();
    }
    if (!video->hasSingleSecurityOrigin()) {
        exceptionState.throwSecurityError("The source video contains image data from multiple origins.");
        return ScriptPromise();
    }
    if (!video->webMediaPlayer()->didPassCORSAccessCheck()
        && eventTarget.toDOMWindow()->document()->securityOrigin()->taintsCanvas(video->currentSrc())) {
        exceptionState.throwSecurityError("Cross-origin access to the source video is denied.");
        return ScriptPromise();
    }
    // FIXME: make ImageBitmap creation asynchronous crbug.com/258082
    return fulfillImageBitmap(scriptState, ImageBitmap::create(video, IntRect(sx, sy, sw, sh)));
}
Пример #7
0
ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Local<v8::Value> value)
{
    if (value.IsEmpty())
        return ScriptPromise();
    if (value->IsPromise()) {
        return ScriptPromise(scriptState, value);
    }
    InternalResolver resolver(scriptState);
    ScriptPromise promise = resolver.promise();
    resolver.resolve(value);
    return promise;
}
Пример #8
0
ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, int sx, int sy, int sw, int sh, ExceptionState& exceptionState)
{
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
        return ScriptPromise();
    }
    if (data()->bufferBase()->isNeutered()) {
        exceptionState.throwDOMException(InvalidStateError, "The source data has been neutered.");
        return ScriptPromise();
    }
    return ImageBitmapSource::fulfillImageBitmap(scriptState, ImageBitmap::create(this, IntRect(sx, sy, sw, sh)));
}
Пример #9
0
ScriptPromise ScriptPromise::cast(ScriptState* scriptState, v8::Handle<v8::Value> value)
{
    if (value.IsEmpty())
        return ScriptPromise();
    if (value->IsPromise()) {
        return ScriptPromise(scriptState, value);
    }
    RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
    ScriptPromise promise = resolver->promise();
    resolver->resolve(value);
    return promise;
}
Пример #10
0
ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& es)
{
    WebKit::WebCryptoKeyUsageMask keyUsages;
    if (!Key::parseUsageMask(rawKeyUsages, keyUsages, es))
        return ScriptPromise();

    WebKit::WebCryptoAlgorithm algorithm;
    if (!normalizeAlgorithm(rawAlgorithm, GenerateKey, algorithm, es))
        return ScriptPromise();

    RefPtr<CryptoResult> result = CryptoResult::create();
    WebKit::Platform::current()->crypto()->generateKey(algorithm, extractable, keyUsages, result->result());
    return result->promise();
}
Пример #11
0
ScriptPromise Cache::keys(ScriptState* scriptState, const String& requestString, const CacheQueryOptions& options, ExceptionState& exceptionState)
{
    Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
    if (exceptionState.hadException())
        return ScriptPromise();
    return keysImpl(scriptState, request, options);
}
Пример #12
0
  void revoke() {
    ExecutionContext* executionContext = m_scriptState->getExecutionContext();
    if (!executionContext)
      return;

    ScriptState::Scope scope(m_scriptState);
    v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate());
    v8::Local<v8::Value> reason =
        m_exception.newLocal(m_scriptState->isolate());
    // Either collected or https://crbug.com/450330
    if (value.IsEmpty() || !value->IsPromise())
      return;

    EventTarget* target = executionContext->errorEventTarget();
    if (target &&
        !executionContext->shouldSanitizeScriptError(m_resourceName,
                                                     m_corsStatus)) {
      PromiseRejectionEventInit init;
      init.setPromise(ScriptPromise(m_scriptState, value));
      init.setReason(ScriptValue(m_scriptState, reason));
      PromiseRejectionEvent* event = PromiseRejectionEvent::create(
          m_scriptState, EventTypeNames::rejectionhandled, init);
      target->dispatchEvent(event);
    }

    if (m_shouldLogToConsole && m_promiseRejectionId) {
      V8PerIsolateData* data = V8PerIsolateData::from(m_scriptState->isolate());
      if (data->threadDebugger())
        data->threadDebugger()->promiseRejectionRevoked(
            m_scriptState->context(), m_promiseRejectionId);
    }
  }
Пример #13
0
ScriptPromise Cache::add(ScriptState* scriptState, const String& requestString, ExceptionState& exceptionState)
{
    Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
    if (exceptionState.hadException())
        return ScriptPromise();
    return addImpl(scriptState, request);
}
Пример #14
0
ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontString, const String& text)
{
    if (!inActiveDocumentContext())
        return ScriptPromise();

    Font font;
    if (!resolveFontStyle(fontString, font)) {
        ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
        ScriptPromise promise = resolver->promise();
        resolver->reject(DOMException::create(SyntaxError, "Could not resolve '" + fontString + "' as a font."));
        return promise;
    }

    FontFaceCache* fontFaceCache = document()->styleEngine().fontSelector()->fontFaceCache();
    FontFaceArray faces;
    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
        CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDescription(), f->family());
        if (segmentedFontFace)
            segmentedFontFace->match(text, faces);
    }

    RefPtrWillBeRawPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(faces, scriptState);
    ScriptPromise promise = resolver->promise();
    resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null.
    return promise;
}
Пример #15
0
ScriptPromise Cache::put(ScriptState* scriptState, const String& requestString, Response* response, ExceptionState& exceptionState)
{
    Request* request = Request::create(scriptState->executionContext(), requestString, exceptionState);
    if (exceptionState.hadException())
        return ScriptPromise();
    return putImpl(scriptState, request, response);
}
Пример #16
0
    void revoke()
    {
        ExecutionContext* executionContext = m_scriptState->executionContext();
        if (!executionContext)
            return;

        ScriptState::Scope scope(m_scriptState);
        v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate());
        v8::Local<v8::Value> reason = m_exception.newLocal(m_scriptState->isolate());
        // Either collected or https://crbug.com/450330
        if (value.IsEmpty() || !value->IsPromise())
            return;

        EventTarget* target = executionContext->errorEventTarget();
        if (RuntimeEnabledFeatures::promiseRejectionEventEnabled() && target && !executionContext->shouldSanitizeScriptError(m_resourceName, m_corsStatus)) {
            PromiseRejectionEventInit init;
            init.setPromise(ScriptPromise(m_scriptState, value));
            init.setReason(ScriptValue(m_scriptState, reason));
            RefPtrWillBeRawPtr<PromiseRejectionEvent> event = PromiseRejectionEvent::create(m_scriptState, EventTypeNames::rejectionhandled, init);
            target->dispatchEvent(event);
        }

        if (m_shouldLogToConsole) {
            RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, RevokedErrorMessageLevel, "Handler added to rejected promise");
            consoleMessage->setRelatedMessageId(m_consoleMessageId);
            executionContext->addConsoleMessage(consoleMessage.release());
        }
    }
Пример #17
0
ScriptPromise ScriptPromise::createPending()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    ASSERT(isolate->InContext());
    v8::Handle<v8::Object> promise = V8PromiseCustom::createPromise(v8::Object::New(isolate), isolate);
    return ScriptPromise(promise, isolate);
}
Пример #18
0
ScriptPromise ImageBitmapSource::createImageBitmap(
    ScriptState* scriptState,
    EventTarget& eventTarget,
    Optional<IntRect> cropRect,
    const ImageBitmapOptions& options,
    ExceptionState& exceptionState) {
  return ScriptPromise();
}
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, HTMLCanvasElement* canvas, int sx, int sy, int sw, int sh, ExceptionState& exceptionState)
{
    // This variant does not work in worker threads.
    ASSERT(eventTarget.toDOMWindow());

    if (!canvas->originClean()) {
        exceptionState.throwSecurityError("The canvas element provided is tainted with cross-origin data.");
        return ScriptPromise();
    }
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
        return ScriptPromise();
    }

    // FIXME: make ImageBitmap creation asynchronous crbug.com/258082
    return fulfillImageBitmap(scriptState, canvas->isPaintable() ? ImageBitmap::create(canvas, IntRect(sx, sy, sw, sh)) : nullptr);
}
Пример #20
0
ScriptPromise Body::rejectInvalidConsumption(ScriptState* scriptState)
{
    if (m_opaque)
        return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "The body is opaque."));
    if (bodyUsed())
        return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read"));
    return ScriptPromise();
}
ScriptPromise OfflineAudioContext::suspendContext(ScriptState* scriptState)
{
    // This CANNOT be called on OfflineAudioContext; this is only to implement
    // the pure virtual interface from AbstractAudioContext.
    RELEASE_ASSERT_NOT_REACHED();

    return ScriptPromise();
}
ScriptPromise ImageBitmapFactories::createImageBitmap(ScriptState* scriptState, EventTarget& eventTarget, ImageBitmap* bitmap, int sx, int sy, int sw, int sh, ExceptionState& exceptionState)
{
    if (!sw || !sh) {
        exceptionState.throwDOMException(IndexSizeError, String::format("The source %s provided is 0.", sw ? "height" : "width"));
        return ScriptPromise();
    }
    // FIXME: make ImageBitmap creation asynchronous crbug.com/258082
    return fulfillImageBitmap(scriptState, ImageBitmap::create(bitmap, IntRect(sx, sy, sw, sh)));
}
Пример #23
0
ScriptPromise ScriptPromise::reject(ScriptState* scriptState, v8::Local<v8::Value> value)
{
    if (value.IsEmpty())
        return ScriptPromise();
    InternalResolver resolver(scriptState);
    ScriptPromise promise = resolver.promise();
    resolver.reject(value);
    return promise;
}
Пример #24
0
ScriptPromise ScriptPromiseResolver::promise()
{
    ASSERT(m_isolate->InContext());
    if (!m_resolver.hasNoValue()) {
        v8::Local<v8::Promise::Resolver> v8Resolver = m_resolver.v8Value().As<v8::Promise::Resolver>();
        return ScriptPromise(v8Resolver->GetPromise(), m_isolate);
    }
    return m_promise;
}
Пример #25
0
ScriptPromise Notification::requestPermission(ScriptState* scriptState, NotificationPermissionCallback* deprecatedCallback)
{
    ExecutionContext* context = scriptState->executionContext();
    if (NotificationPermissionClient* permissionClient = NotificationPermissionClient::from(context))
        return permissionClient->requestPermission(scriptState, deprecatedCallback);

    // The context has been detached. Return a promise that will never settle.
    ASSERT(context->activeDOMObjectsAreStopped());
    return ScriptPromise();
}
Пример #26
0
ScriptPromise ScriptPromise::createPending(ExecutionContext* context)
{
    ASSERT(context);
    v8::Isolate* isolate = toIsolate(context);
    ASSERT(isolate->InContext());
    v8::Handle<v8::Context> v8Context = toV8Context(context, DOMWrapperWorld::current());
    v8::Handle<v8::Object> creationContext = v8Context.IsEmpty() ? v8::Object::New(isolate) : v8Context->Global();
    v8::Handle<v8::Object> promise = V8PromiseCustom::createPromise(creationContext, isolate);
    return ScriptPromise(promise, isolate);
}
Пример #27
0
ScriptPromise FontFaceSet::ready(ScriptState* scriptState)
{
    if (!inActiveDocumentContext())
        return ScriptPromise();
    OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(scriptState);
    ScriptPromise promise = resolver->promise();
    m_readyResolvers.append(resolver.release());
    handlePendingEventsAndPromisesSoon();
    return promise;
}
Пример #28
0
ScriptPromiseResolver::ScriptPromiseResolver(v8::Isolate* isolate)
    : m_isolate(isolate)
{
    ASSERT(isolate->InContext());
    if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) {
        m_resolver = ScriptValue(v8::Promise::Resolver::New(isolate), isolate);
    } else {
        m_promise = ScriptPromise(V8PromiseCustom::createPromise(v8::Object::New(isolate), isolate), isolate);
    }
}
Пример #29
0
ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key, ExceptionState& es)
{
    WebKit::WebCryptoKeyFormat format;
    if (!Key::parseFormat(rawFormat, format, es))
        return ScriptPromise();

    if (!key) {
        es.throwTypeError("Invalid key argument");
        return ScriptPromise();
    }

    if (!key->extractable()) {
        es.throwDOMException(NotSupportedError, "key is not extractable");
        return ScriptPromise();
    }

    RefPtr<CryptoResult> result = CryptoResult::create();
    WebKit::Platform::current()->crypto()->exportKey(format, key->key(), result->result());
    return result->promise();
}
Пример #30
0
    void report()
    {
        if (!m_scriptState->contextIsValid())
            return;
        // If execution termination has been triggered, quietly bail out.
        if (v8::V8::IsExecutionTerminating(m_scriptState->isolate()))
            return;
        ExecutionContext* executionContext = m_scriptState->executionContext();
        if (!executionContext)
            return;

        ScriptState::Scope scope(m_scriptState);
        v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate());
        v8::Local<v8::Value> reason = m_exception.newLocal(m_scriptState->isolate());
        // Either collected or https://crbug.com/450330
        if (value.IsEmpty() || !value->IsPromise())
            return;
        ASSERT(!hasHandler());

        EventTarget* target = executionContext->errorEventTarget();
        if (RuntimeEnabledFeatures::promiseRejectionEventEnabled() && target && !executionContext->shouldSanitizeScriptError(m_resourceName, m_corsStatus)) {
            PromiseRejectionEventInit init;
            init.setPromise(ScriptPromise(m_scriptState, value));
            init.setReason(ScriptValue(m_scriptState, reason));
            init.setCancelable(true);
            RefPtrWillBeRawPtr<PromiseRejectionEvent> event = PromiseRejectionEvent::create(m_scriptState, EventTypeNames::unhandledrejection, init);
            // Log to console if event was not preventDefault()'ed.
            m_shouldLogToConsole = target->dispatchEvent(event);
        }

        if (m_shouldLogToConsole) {
            const String errorMessage = "Uncaught (in promise)";
            Vector<ScriptValue> args;
            args.append(ScriptValue(m_scriptState, v8String(m_scriptState->isolate(), errorMessage)));
            args.append(ScriptValue(m_scriptState, reason));
            RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(m_scriptState, args);

            String embedderErrorMessage = m_errorMessage;
            if (embedderErrorMessage.isEmpty())
                embedderErrorMessage = errorMessage;
            else if (embedderErrorMessage.startsWith("Uncaught "))
                embedderErrorMessage.insert(" (in promise)", 8);

            RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, embedderErrorMessage, m_resourceName, m_lineNumber, m_columnNumber);
            consoleMessage->setScriptArguments(arguments);
            consoleMessage->setCallStack(m_callStack);
            consoleMessage->setScriptId(m_scriptId);
            m_consoleMessageId = consoleMessage->assignMessageId();
            executionContext->addConsoleMessage(consoleMessage.release());
        }

        m_callStack.clear();
    }