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::tryToOpenDatabaseBackend(DatabaseContext& backendContext, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, bool setVersionInNewDatabase, OpenAttempt attempt) { ExceptionOr<void> preflightResult; switch (attempt) { case FirstTryToOpenDatabase: preflightResult = DatabaseTracker::singleton().canEstablishDatabase(backendContext, name, estimatedSize); break; case RetryOpenDatabase: preflightResult = DatabaseTracker::singleton().retryCanEstablishDatabase(backendContext, name, estimatedSize); break; } if (preflightResult.hasException()) return preflightResult.releaseException(); auto database = adoptRef(*new Database(backendContext, name, expectedVersion, displayName, estimatedSize)); auto openResult = database->openAndVerifyVersion(setVersionInNewDatabase); if (openResult.hasException()) return openResult.releaseException(); // FIXME: What guarantees backendContext.securityOrigin() is non-null? DatabaseTracker::singleton().setDatabaseDetails(backendContext.securityOrigin(), name, displayName, estimatedSize); return WTFMove(database); }
bool JSStorage::putDelegate(ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot&, bool& putResult) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // Only perform the custom put if the object doesn't have a native property by this name. // Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check // the native property slots manually. PropertySlot slot { this, PropertySlot::InternalMethodType::GetOwnProperty }; JSValue prototype = this->getPrototypeDirect(); if (prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot)) return false; if (propertyName.isSymbol()) return false; String stringValue = value.toWTFString(state); RETURN_IF_EXCEPTION(scope, true); auto setItemResult = wrapped().setItem(propertyNameToString(propertyName), stringValue); if (setItemResult.hasException()) { propagateException(*state, scope, setItemResult.releaseException()); return true; } putResult = true; return true; }
ExceptionOr<String> FileReaderSync::startLoadingString(ScriptExecutionContext& scriptExecutionContext, FileReaderLoader& loader, Blob& blob) { auto result = startLoading(scriptExecutionContext, loader, blob); if (result.hasException()) return result.releaseException(); return loader.stringResult(); }
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); }
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(); }
JSValue JSWebKitSubtleCrypto::digest(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 2) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); auto parameters = JSCryptoAlgorithmDictionary::createParametersForDigest(state, scope, algorithm->identifier(), state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); auto data = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(1)); RETURN_IF_EXCEPTION(scope, { }); RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable { fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size()); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(); // FIXME: This should reject with an Exception. }; auto result = algorithm->digest(*parameters, data, WTFMove(successCallback), WTFMove(failureCallback)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
ExceptionOr<RefPtr<ArrayBuffer>> FileReaderSync::readAsArrayBuffer(ScriptExecutionContext& scriptExecutionContext, Blob& blob) { FileReaderLoader loader(FileReaderLoader::ReadAsArrayBuffer, 0); auto result = startLoading(scriptExecutionContext, loader, blob); if (result.hasException()) return result.releaseException(); return loader.arrayBufferResult(); }
ExceptionOr<Ref<WebKitCSSMatrix>> WebKitCSSMatrix::create(const String& string) { auto result = adoptRef(*new WebKitCSSMatrix); auto setMatrixValueResult = result->setMatrixValue(string); if (setMatrixValueResult.hasException()) return setMatrixValueResult.releaseException(); return WTFMove(result); }
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 { }; }
JSValue JSWebKitSubtleCrypto::verify(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 4) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(0)); ASSERT(scope.exception() || algorithm); if (!algorithm) return jsUndefined(); auto parameters = JSCryptoAlgorithmDictionary::createParametersForVerify(&state, algorithm->identifier(), state.uncheckedArgument(0)); ASSERT(scope.exception() || parameters); if (!parameters) return jsUndefined(); RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(state.uncheckedArgument(1)); if (!key) return throwTypeError(&state, scope); if (!key->allows(CryptoKeyUsageVerify)) { wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'verify'")); setDOMException(&state, NOT_SUPPORTED_ERR); return jsUndefined(); } CryptoOperationData signature; auto success = cryptoOperationDataFromJSValue(&state, state.uncheckedArgument(2), signature); ASSERT(scope.exception() || success); if (!success) return jsUndefined(); CryptoOperationData data; success = cryptoOperationDataFromJSValue(&state, state.uncheckedArgument(3), data); ASSERT(scope.exception() || success); if (!success) return jsUndefined(); RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](bool result) mutable { wrapper->resolve(result); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(nullptr); }; auto result = algorithm->verify(*parameters, *key, signature, data, WTFMove(successCallback), WTFMove(failureCallback)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
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> 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 { }; }
JSValue JSWebKitSubtleCrypto::generateKey(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 1) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(0)); ASSERT(scope.exception() || algorithm); if (!algorithm) return jsUndefined(); auto parameters = JSCryptoAlgorithmDictionary::createParametersForGenerateKey(&state, algorithm->identifier(), state.uncheckedArgument(0)); ASSERT(scope.exception() || parameters); if (!parameters) return jsUndefined(); bool extractable = false; if (state.argumentCount() >= 2) { extractable = state.uncheckedArgument(1).toBoolean(&state); RETURN_IF_EXCEPTION(scope, JSValue()); } CryptoKeyUsageBitmap keyUsages = 0; if (state.argumentCount() >= 3) { auto success = cryptoKeyUsagesFromJSValue(state, state.argument(2), keyUsages); ASSERT(scope.exception() || success); if (!success) return jsUndefined(); } RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](CryptoKey* key, CryptoKeyPair* keyPair) mutable { ASSERT(key || keyPair); ASSERT(!key || !keyPair); if (key) wrapper->resolve(key); else wrapper->resolve(keyPair); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(nullptr); }; auto result = algorithm->generateKey(*parameters, extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback), *scriptExecutionContextFromExecState(&state)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
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> PaymentHandler::canCreateSession(Document& document) { #if ENABLE(APPLE_PAY) auto result = PaymentSession::canCreateSession(document); if (result.hasException()) return Exception { SecurityError, result.releaseException().releaseMessage() }; #else UNUSED_PARAM(document); #endif return { }; }
ExceptionOr<RefPtr<RTCConfiguration>> RTCConfiguration::create(const Dictionary& configuration) { if (configuration.isUndefinedOrNull()) return nullptr; auto result = adoptRef(*new RTCConfiguration); auto initializeResult = result->initialize(configuration); if (initializeResult.hasException()) return initializeResult.releaseException(); return RefPtr<RTCConfiguration> { WTFMove(result) }; }
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 DOMFileSystem::getFile(ScriptExecutionContext& context, FileSystemFileEntry& fileEntry, GetFileCallback&& completionCallback) { auto virtualPath = fileEntry.virtualPath(); auto fullPath = evaluatePath(virtualPath); m_workQueue->dispatch([context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable { auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::File); callOnMainThread([context = WTFMove(context), fullPath = crossThreadCopy(fullPath), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { if (validatedVirtualPath.hasException()) completionCallback(validatedVirtualPath.releaseException()); else completionCallback(File::create(fullPath)); }); }); }
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(); }
ExceptionOr<int> CSSStyleSheet::addRule(const String& selector, const String& style, std::optional<unsigned> index) { StringBuilder text; text.append(selector); text.appendLiteral(" { "); text.append(style); if (!style.isEmpty()) text.append(' '); text.append('}'); auto insertRuleResult = insertRule(text.toString(), index.value_or(length())); if (insertRuleResult.hasException()) return insertRuleResult.releaseException(); // As per Microsoft documentation, always return -1. return -1; }
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); }
JSValue JSWebKitSubtleCrypto::verify(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 4) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); auto parameters = JSCryptoAlgorithmDictionary::createParametersForVerify(state, scope, algorithm->identifier(), state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(1)); if (!key) return throwTypeError(&state, scope); if (!key->allows(CryptoKeyUsageVerify)) { wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'verify'")); throwNotSupportedError(state, scope); return jsUndefined(); } auto signature = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(2)); RETURN_IF_EXCEPTION(scope, { }); auto data = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(3)); RETURN_IF_EXCEPTION(scope, { }); RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](bool result) mutable { wrapper->resolve<IDLBoolean>(result); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(); // FIXME: This should reject with an Exception. }; auto result = algorithm->verify(*parameters, *key, signature, data, WTFMove(successCallback), WTFMove(failureCallback)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
JSValue JSWebKitSubtleCrypto::generateKey(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (state.argumentCount() < 1) return throwException(&state, scope, createNotEnoughArgumentsError(&state)); auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); auto parameters = JSCryptoAlgorithmDictionary::createParametersForGenerateKey(state, scope, algorithm->identifier(), state.uncheckedArgument(0)); RETURN_IF_EXCEPTION(scope, { }); bool extractable = state.argument(1).toBoolean(&state); RETURN_IF_EXCEPTION(scope, { }); CryptoKeyUsageBitmap keyUsages = 0; if (state.argumentCount() >= 3) { keyUsages = cryptoKeyUsagesFromJSValue(state, scope, state.uncheckedArgument(2)); RETURN_IF_EXCEPTION(scope, { }); } RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow()); auto promise = wrapper->promise(); auto successCallback = [wrapper](KeyOrKeyPair&& keyOrKeyPair) mutable { WTF::switchOn(keyOrKeyPair, [&wrapper] (RefPtr<CryptoKey>& key) { wrapper->resolve<IDLInterface<CryptoKey>>(*key); }, [&wrapper] (CryptoKeyPair& keyPair) { wrapper->resolve<IDLDictionary<CryptoKeyPair>>(keyPair); } ); }; auto failureCallback = [wrapper]() mutable { wrapper->reject(); // FIXME: This should reject with an Exception. }; auto result = algorithm->generateKey(*parameters, extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback), *scriptExecutionContextFromExecState(&state)); if (result.hasException()) { propagateException(state, scope, result.releaseException()); return { }; } return promise; }
ExceptionOr<Ref<FontFace>> FontFace::create(JSC::ExecState& state, Document& document, const String& family, JSC::JSValue source, const Descriptors& descriptors) { auto result = adoptRef(*new FontFace(document.fontSelector())); bool dataRequiresAsynchronousLoading = true; auto setFamilyResult = result->setFamily(family); if (setFamilyResult.hasException()) return setFamilyResult.releaseException(); if (source.isString()) { auto value = FontFace::parseString(source.getString(&state), CSSPropertySrc); if (!is<CSSValueList>(value.get())) return Exception { SYNTAX_ERR }; CSSFontFace::appendSources(result->backing(), downcast<CSSValueList>(*value), &document, false); } else if (auto arrayBufferView = toUnsharedArrayBufferView(source)) dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), arrayBufferView.releaseNonNull()); else if (auto arrayBuffer = toUnsharedArrayBuffer(source)) { auto arrayBufferView = JSC::Uint8Array::create(arrayBuffer, 0, arrayBuffer->byteLength()); dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), arrayBufferView.releaseNonNull()); } // These ternaries match the default strings inside the FontFaceDescriptors dictionary inside FontFace.idl. auto setStyleResult = result->setStyle(descriptors.style.isEmpty() ? ASCIILiteral("normal") : descriptors.style); if (setStyleResult.hasException()) return setStyleResult.releaseException(); auto setWeightResult = result->setWeight(descriptors.weight.isEmpty() ? ASCIILiteral("normal") : descriptors.weight); if (setWeightResult.hasException()) return setWeightResult.releaseException(); auto setStretchResult = result->setStretch(descriptors.stretch.isEmpty() ? ASCIILiteral("normal") : descriptors.stretch); if (setStretchResult.hasException()) return setStretchResult.releaseException(); auto setUnicodeRangeResult = result->setUnicodeRange(descriptors.unicodeRange.isEmpty() ? ASCIILiteral("U+0-10FFFF") : descriptors.unicodeRange); if (setUnicodeRangeResult.hasException()) return setUnicodeRangeResult.releaseException(); auto setVariantResult = result->setVariant(descriptors.variant.isEmpty() ? ASCIILiteral("normal") : descriptors.variant); if (setVariantResult.hasException()) return setVariantResult.releaseException(); auto setFeatureSettingsResult = result->setFeatureSettings(descriptors.featureSettings.isEmpty() ? ASCIILiteral("normal") : descriptors.featureSettings); if (setFeatureSettingsResult.hasException()) return setFeatureSettingsResult.releaseException(); if (!dataRequiresAsynchronousLoading) { result->backing().load(); ASSERT(result->backing().status() == CSSFontFace::Status::Success); } return WTFMove(result); }
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())); }); }); }
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(); }); }); }