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)); }
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 { }; }
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 { }; }
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(); }
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); }
float SVGLengthValue::value(const SVGLengthContext& context) const { auto result = valueForBindings(context); if (result.hasException()) return 0; return result.releaseReturnValue(); }
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); }
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()); }
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 { }; }
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); }
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 { }; }
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 { }; }
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 { }; }
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); }
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); }
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())); }); }); }
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 { }; }
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(); }
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(); }); }); }
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; }
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() }; }
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; }