Пример #1
0
void CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey(SubtleCrypto::KeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
{
    const auto& rsaKey = downcast<CryptoKeyRSA>(key.get());

    if (!rsaKey.keySizeInBits()) {
        exceptionCallback(OperationError);
        return;
    }

    KeyData result;
    switch (format) {
    case SubtleCrypto::KeyFormat::Jwk: {
        JsonWebKey jwk = rsaKey.exportJwk();
        switch (rsaKey.hashAlgorithmIdentifier()) {
        case CryptoAlgorithmIdentifier::SHA_1:
            jwk.alg = String(ALG1);
            break;
        case CryptoAlgorithmIdentifier::SHA_224:
            jwk.alg = String(ALG224);
            break;
        case CryptoAlgorithmIdentifier::SHA_256:
            jwk.alg = String(ALG256);
            break;
        case CryptoAlgorithmIdentifier::SHA_384:
            jwk.alg = String(ALG384);
            break;
        case CryptoAlgorithmIdentifier::SHA_512:
            jwk.alg = String(ALG512);
            break;
        default:
            ASSERT_NOT_REACHED();
        }
        result = WTFMove(jwk);
        break;
    }
    case SubtleCrypto::KeyFormat::Spki: {
        auto spki = rsaKey.exportSpki();
        if (spki.hasException()) {
            exceptionCallback(spki.releaseException().code());
            return;
        }
        result = spki.releaseReturnValue();
        break;
    }
    case SubtleCrypto::KeyFormat::Pkcs8: {
        auto pkcs8 = rsaKey.exportPkcs8();
        if (pkcs8.hasException()) {
            exceptionCallback(pkcs8.releaseException().code());
            return;
        }
        result = pkcs8.releaseReturnValue();
        break;
    }
    default:
        exceptionCallback(NOT_SUPPORTED_ERR);
        return;
    }

    callback(format, WTFMove(result));
}
Пример #2
0
ExceptionOr<void> MessagePort::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
{
    Vector<RefPtr<MessagePort>> ports;
    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
    if (message.hasException())
        return message.releaseException();

    if (!isEntangled())
        return { };
    ASSERT(m_scriptExecutionContext);

    std::unique_ptr<MessagePortChannelArray> channels;
    // Make sure we aren't connected to any of the passed-in ports.
    if (!ports.isEmpty()) {
        for (auto& dataPort : ports) {
            if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort.get()))
                return Exception { DATA_CLONE_ERR };
        }
        auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports));
        if (disentangleResult.hasException())
            return disentangleResult.releaseException();
        channels = disentangleResult.releaseReturnValue();
    }
    m_entangledChannel->postMessageToRemote(message.releaseReturnValue(), WTFMove(channels));
    return { };
}
Пример #3
0
ExceptionOr<void> Worker::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
{
    Vector<RefPtr<MessagePort>> ports;
    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
    if (message.hasException())
        return message.releaseException();

    // Disentangle the port in preparation for sending it to the remote context.
    auto channels = MessagePort::disentanglePorts(WTFMove(ports));
    if (channels.hasException())
        return channels.releaseException();
    m_contextProxy.postMessageToWorkerGlobalScope(message.releaseReturnValue(), channels.releaseReturnValue());
    return { };
}
Пример #4
0
ExceptionOr<Ref<Database>> DatabaseManager::openDatabase(ScriptExecutionContext& context, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, RefPtr<DatabaseCallback>&& creationCallback)
{
    ScriptController::initializeThreading();

    bool setVersionInNewDatabase = !creationCallback;
    auto openResult = openDatabaseBackend(context, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase);
    if (openResult.hasException())
        return openResult.releaseException();

    RefPtr<Database> database = openResult.releaseReturnValue();

    auto databaseContext = this->databaseContext(context);
    databaseContext->setHasOpenDatabases();
    InspectorInstrumentation::didOpenDatabase(&context, database.copyRef(), context.securityOrigin()->host(), name, expectedVersion);

    if (database->isNew() && creationCallback.get()) {
        LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database.get());
        database->setHasPendingCreationEvent(true);
        database->m_scriptExecutionContext->postTask([creationCallback, database] (ScriptExecutionContext&) {
            creationCallback->handleEvent(database.get());
            database->setHasPendingCreationEvent(false);
        });
    }

    return database.releaseNonNull();
}
Пример #5
0
ExceptionOr<Ref<Worker>> Worker::create(ScriptExecutionContext& context, const String& url, JSC::RuntimeFlags runtimeFlags)
{
    ASSERT(isMainThread());

    // We don't currently support nested workers, so workers can only be created from documents.
    ASSERT_WITH_SECURITY_IMPLICATION(context.isDocument());

    auto worker = adoptRef(*new Worker(context, runtimeFlags));

    worker->suspendIfNeeded();

    bool shouldBypassMainWorldContentSecurityPolicy = context.shouldBypassMainWorldContentSecurityPolicy();
    auto scriptURL = worker->resolveURL(url, shouldBypassMainWorldContentSecurityPolicy);
    if (scriptURL.hasException())
        return scriptURL.releaseException();

    worker->m_shouldBypassMainWorldContentSecurityPolicy = shouldBypassMainWorldContentSecurityPolicy;

    // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
    worker->setPendingActivity(worker.ptr());

    worker->m_scriptLoader = WorkerScriptLoader::create();
    auto contentSecurityPolicyEnforcement = shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceChildSrcDirective;
    worker->m_scriptLoader->loadAsynchronously(&context, scriptURL.releaseReturnValue(), FetchOptions::Mode::SameOrigin, contentSecurityPolicyEnforcement, worker->m_identifier, worker.ptr());
    return WTFMove(worker);
}
Пример #6
0
float SVGLengthValue::value(const SVGLengthContext& context) const
{
    auto result = valueForBindings(context);
    if (result.hasException())
        return 0;
    return result.releaseReturnValue();
}
Пример #7
0
ExceptionOr<Ref<IDBRequest>> IDBIndex::getAllKeys(ExecState& execState, JSValue key, Optional<uint32_t> count)
{
    auto onlyResult = IDBKeyRange::only(execState, key);
    if (onlyResult.hasException())
        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'getAllKeys' on 'IDBIndex': The parameter is not a valid key.") };

    return getAllKeys(execState, onlyResult.releaseReturnValue(), count);
}
Пример #8
0
ExceptionOr<void> ShadowRoot::setInnerHTML(const String& markup)
{
    if (isOrphan())
        return Exception { INVALID_ACCESS_ERR };
    auto fragment = createFragmentForInnerOuterHTML(*host(), markup, AllowScriptingContent);
    if (fragment.hasException())
        return fragment.releaseException();
    return replaceChildrenWithFragment(*this, fragment.releaseReturnValue());
}
Пример #9
0
ExceptionOr<void> Worker::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports)
{
    // Disentangle the port in preparation for sending it to the remote context.
    auto channels = MessagePort::disentanglePorts(WTFMove(ports));
    if (channels.hasException())
        return channels.releaseException();
    m_contextProxy->postMessageToWorkerGlobalScope(WTFMove(message), channels.releaseReturnValue());
    return { };
}
Пример #10
0
ExceptionOr<Ref<IDBRequest>> IDBIndex::openKeyCursor(ExecState& execState, JSValue key, const String& direction)
{
    LOG(IndexedDB, "IDBIndex::openKeyCursor");

    auto keyRange = IDBKeyRange::only(execState, key);
    if (keyRange.hasException())
        return Exception { IDBDatabaseException::DataError, ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The parameter is not a valid key.") };
    return openKeyCursor(execState, keyRange.releaseReturnValue().ptr(), direction);
}
Пример #11
0
ExceptionOr<void> CryptoAlgorithmRSA_OAEP::platformDecrypt(const CryptoAlgorithmRsaOaepParamsDeprecated& parameters, const CryptoKeyRSA& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
{
    ASSERT(parameters.hasLabel || parameters.label.isEmpty());
    auto result = decryptRSA_OAEP(parameters.hash, parameters.label, key.platformKey(), key.keySizeInBits(), data.first, data.second);
    if (result.hasException()) {
        failureCallback();
        return { };
    }
    callback(result.releaseReturnValue());
    return { };
}
Пример #12
0
ExceptionOr<void> SVGLengthValue::setValue(float value, const SVGLengthContext& context)
{
    // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
    if (extractType(m_unit) == LengthTypePercentage)
        value = value / 100;

    auto convertedValue = context.convertValueFromUserUnits(value, extractMode(m_unit), extractType(m_unit));
    if (convertedValue.hasException())
        return convertedValue.releaseException();
    m_valueInSpecifiedUnits = convertedValue.releaseReturnValue();
    return { };
}
Пример #13
0
ExceptionOr<void> RTCConfiguration::initialize(const Dictionary& configuration)
{
    ArrayValue iceServers;
    bool ok = configuration.get("iceServers", iceServers);
    if (!ok || iceServers.isUndefinedOrNull())
        return Exception { TYPE_MISMATCH_ERR };

    size_t numberOfServers;
    ok = iceServers.length(numberOfServers);
    if (!ok)
        return Exception { TYPE_MISMATCH_ERR };
    if (!numberOfServers)
        return Exception { INVALID_ACCESS_ERR };

    for (size_t i = 0; i < numberOfServers; ++i) {
        Dictionary iceServerDict;
        ok = iceServers.get(i, iceServerDict);
        if (!ok)
            return Exception { TYPE_MISMATCH_ERR };

        auto server = parseIceServer(iceServerDict);
        if (server.hasException())
            return server.releaseException();

        m_iceServers.append(server.releaseReturnValue());
    }

    String iceTransportPolicy;
    if (configuration.get("iceTransportPolicy", iceTransportPolicy)) {
        if (iceTransportPolicy == "relay")
            m_iceTransportPolicy = IceTransportPolicy::Relay;
        else if (iceTransportPolicy == "all")
            m_iceTransportPolicy = IceTransportPolicy::All;
        else
            return Exception { TypeError };
    }

    String bundlePolicy;
    if (configuration.get("bundlePolicy", bundlePolicy)) {
        if (bundlePolicy == "balanced")
            m_bundlePolicy = BundlePolicy::Balanced;
        else if (bundlePolicy == "max-compat")
            m_bundlePolicy = BundlePolicy::MaxCompat;
        else if (bundlePolicy == "max-bundle")
            m_bundlePolicy = BundlePolicy::MaxBundle;
        else
            return Exception { TypeError };
    }

    return { };
}
Пример #14
0
void JSStorage::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    auto& thisObject = *jsCast<JSStorage*>(object);
    auto lengthResult = thisObject.wrapped().length();
    if (lengthResult.hasException()) {
        propagateException(*state, scope, lengthResult.releaseException());
        return;
    }
    unsigned length = lengthResult.releaseReturnValue();
    for (unsigned i = 0; i < length; ++i) {
        auto keyResult = thisObject.wrapped().key(i);
        if (keyResult.hasException()) {
            propagateException(*state, scope, lengthResult.releaseException());
            return;
        }
        propertyNames.add(Identifier::fromString(state, keyResult.releaseReturnValue()));
    }
        
    Base::getOwnPropertyNames(&thisObject, state, propertyNames, mode);
}
Пример #15
0
static gboolean webkit_dom_html_embed_element_dispatch_event(WebKitDOMEventTarget* target, WebKitDOMEvent* event, GError** error)
{
    WebCore::Event* coreEvent = WebKit::core(event);
    if (!coreEvent)
        return false;
    WebCore::HTMLEmbedElement* coreTarget = static_cast<WebCore::HTMLEmbedElement*>(WEBKIT_DOM_OBJECT(target)->coreObject);

    auto result = coreTarget->dispatchEventForBindings(*coreEvent);
    if (result.hasException()) {
        WebCore::ExceptionCodeDescription description(result.releaseException().code());
        g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), description.code, description.name);
        return false;
    }
    return result.releaseReturnValue();
}
bool JSTestNamedDeleterThrowingException::deleteProperty(JSCell* cell, ExecState* state, PropertyName propertyName)
{
    auto& thisObject = *jsCast<JSTestNamedDeleterThrowingException*>(cell);
    auto& impl = thisObject.wrapped();
    if (isVisibleNamedProperty<OverrideBuiltins::No>(*state, thisObject, propertyName)) {
        auto result = impl.deleteNamedProperty(propertyNameToString(propertyName));
        if (result.hasException()) {
            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
            propagateException(*state, throwScope, result.releaseException());
            return true;
        }

        return result.releaseReturnValue();
    }
    return JSObject::deleteProperty(cell, state, propertyName);
}
Пример #17
0
void DOMFileSystem::getParent(ScriptExecutionContext& context, FileSystemEntry& entry, GetParentCallback&& completionCallback)
{
    ASSERT(&entry.filesystem() == this);

    auto virtualPath = resolveRelativeVirtualPath(entry.virtualPath(), "..");
    ASSERT(virtualPath[0] == '/');
    auto fullPath = evaluatePath(virtualPath);
    m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
        auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::Directory);
        callOnMainThread([this, context = WTFMove(context), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
            if (validatedVirtualPath.hasException())
                completionCallback(validatedVirtualPath.releaseException());
            else
                completionCallback(FileSystemDirectoryEntry::create(context, *this, validatedVirtualPath.releaseReturnValue()));
        });
    });
}
Пример #18
0
ExceptionOr<void> SVGLengthValue::convertToSpecifiedUnits(unsigned short type, const SVGLengthContext& context)
{
    if (type == LengthTypeUnknown || type > LengthTypePC)
        return Exception { NOT_SUPPORTED_ERR };

    auto valueInUserUnits = valueForBindings(context);
    if (valueInUserUnits.hasException())
        return valueInUserUnits.releaseException();

    auto originalUnitAndType = m_unit;
    m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type));
    auto result = setValue(valueInUserUnits.releaseReturnValue(), context);
    if (result.hasException()) {
        m_unit = originalUnitAndType;
        return result.releaseException();
    }

    return { };
}
Пример #19
0
void SplitTextNodeCommand::doApply()
{
    ContainerNode* parent = m_text2->parentNode();
    if (!parent || !parent->hasEditableStyle())
        return;

    auto result = m_text2->substringData(0, m_offset);
    if (result.hasException())
        return;
    auto prefixText = result.releaseReturnValue();
    if (prefixText.isEmpty())
        return;

    m_text1 = Text::create(document(), WTFMove(prefixText));
    ASSERT(m_text1);
    document().markers().copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);

    insertText1AndTrimText2();
}
Пример #20
0
void CryptoAlgorithmRSA_OAEP::platformDecrypt(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& cipherText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
{
    context.ref();
    workQueue.dispatch([parameters = WTFMove(parameters), key = WTFMove(key), cipherText = WTFMove(cipherText), callback = WTFMove(callback), exceptionCallback = WTFMove(exceptionCallback), &context]() mutable {
        auto& rsaParameters = downcast<CryptoAlgorithmRsaOaepParams>(*parameters);
        auto& rsaKey = downcast<CryptoKeyRSA>(key.get());
        auto result = decryptRSA_OAEP(rsaKey.hashAlgorithmIdentifier(), rsaParameters.labelVector(), rsaKey.platformKey(), rsaKey.keySizeInBits(), cipherText.data(), cipherText.size());
        if (result.hasException()) {
            context.postTask([exceptionCallback = WTFMove(exceptionCallback), ec = result.releaseException().code()](ScriptExecutionContext& context) {
                exceptionCallback(ec);
                context.deref();
            });
            return;
        }
        context.postTask([callback = WTFMove(callback), result = result.releaseReturnValue()](ScriptExecutionContext& context) {
            callback(result);
            context.deref();
        });
    });
}
Пример #21
0
bool JSStorage::nameGetter(ExecState* state, PropertyName propertyName, JSValue& value)
{
    if (propertyName.isSymbol())
        return false;

    auto item = wrapped().getItem(propertyNameToString(propertyName));
    if (item.hasException()) {
        auto& vm = state->vm();
        auto scope = DECLARE_THROW_SCOPE(vm);
        propagateException(*state, scope, item.releaseException());
        return false;
    }

    auto string = item.releaseReturnValue();
    if (string.isNull())
        return false;

    value = jsStringWithCache(state, string);
    return true;
}
Пример #22
0
void FontFaceSet::load(const String& font, const String& text, LoadPromise&& promise)
{
    auto matchingFacesResult = m_backing->matchingFaces(font, text);
    if (matchingFacesResult.hasException()) {
        promise.reject(matchingFacesResult.releaseException());
        return;
    }
    auto matchingFaces = matchingFacesResult.releaseReturnValue();

    if (matchingFaces.isEmpty()) {
        promise.resolve(Vector<RefPtr<FontFace>>());
        return;
    }

    for (auto& face : matchingFaces)
        face.get().load();

    for (auto& face : matchingFaces) {
        if (face.get().status() == CSSFontFace::Status::Failure) {
            promise.reject(NETWORK_ERR);
            return;
        }
    }

    auto pendingPromise = PendingPromise::create(WTFMove(promise));
    bool waiting = false;

    for (auto& face : matchingFaces) {
        pendingPromise->faces.append(face.get().wrapper());
        if (face.get().status() == CSSFontFace::Status::Success)
            continue;
        waiting = true;
        ASSERT(face.get().existingWrapper());
        m_pendingPromises.add(face.get().existingWrapper(), Vector<Ref<PendingPromise>>()).iterator->value.append(pendingPromise.copyRef());
    }

    if (!waiting)
        pendingPromise->promise.resolve(pendingPromise->faces);
}
ExceptionOr<RefPtr<Database>> DOMWindowWebDatabase::openDatabase(DOMWindow& window, const String& name, const String& version, const String& displayName, unsigned estimatedSize, RefPtr<DatabaseCallback>&& creationCallback)
{
    if (!window.isCurrentlyDisplayedInFrame())
        return RefPtr<Database> { nullptr };
    auto& manager = DatabaseManager::singleton();
    if (!manager.isAvailable())
        return Exception { SecurityError };
    auto* document = window.document();
    if (!document)
        return Exception { SecurityError };
    document->addConsoleMessage(MessageSource::Storage, MessageLevel::Warning, "Web SQL is deprecated. Please use IndexedDB instead.");

    auto& securityOrigin = document->securityOrigin();
    if (!securityOrigin.canAccessDatabase(document->topOrigin()))
        return Exception { SecurityError };
    auto result = manager.openDatabase(*window.document(), name, version, displayName, estimatedSize, WTFMove(creationCallback));
    if (result.hasException()) {
        // FIXME: To preserve our past behavior, this discards the error string in the exception.
        // At a later time we may decide that we want to use the error strings, and if so we can just return the exception as is.
        return Exception { result.releaseException().code() };
    }
    return RefPtr<Database> { result.releaseReturnValue() };
}
Пример #24
0
float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode)
{
    if (length.isPercent()) {
        auto result = convertValueFromPercentageToUserUnits(length.value() / 100, mode);
        if (result.hasException())
            return 0;
        return result.releaseReturnValue();
    }
    if (length.isAuto() || !length.isSpecified())
        return 0;

    FloatSize viewportSize;
    determineViewport(viewportSize);

    switch (mode) {
    case LengthModeWidth:
        return floatValueForLength(length, viewportSize.width());
    case LengthModeHeight:
        return floatValueForLength(length, viewportSize.height());
    case LengthModeOther:
        return floatValueForLength(length, std::sqrt(viewportSize.diagonalLengthSquared() / 2));
    };
    return 0;
}