/* * Copyright (C) 2011-2021 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "WebCoreArgumentCoders.h" #include "DataReference.h" #include "ShareableBitmap.h" #include "ShareableResource.h" #include "SharedBufferDataReference.h" #include "StreamConnectionEncoder.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if PLATFORM(COCOA) #include "ArgumentCodersCF.h" #endif #if PLATFORM(IOS_FAMILY) #include #include #endif // PLATFORM(IOS_FAMILY) #if ENABLE(WIRELESS_PLAYBACK_TARGET) #include #endif #if ENABLE(MEDIA_STREAM) #include #include #endif #if ENABLE(IMAGE_ANALYSIS) #include #endif // FIXME: Seems like we could use std::tuple to cut down the code below a lot! namespace IPC { using namespace WebCore; using namespace WebKit; static void encodeSharedBuffer(Encoder& encoder, const SharedBuffer* buffer) { bool isNull = !buffer; encoder << isNull; if (isNull) return; uint64_t bufferSize = buffer->size(); encoder << bufferSize; if (!bufferSize) return; #if USE(UNIX_DOMAIN_SOCKETS) // Do not use shared memory for SharedBuffer encoding in Unix, because it's easy to reach the // maximum number of file descriptors open per process when sending large data in small chunks // over the IPC. ConnectionUnix.cpp already uses shared memory to send any IPC message that is // too large. See https://bugs.webkit.org/show_bug.cgi?id=208571. for (const auto& element : *buffer) encoder.encodeFixedLengthData(element.segment->data(), element.segment->size(), 1); #else SharedMemory::Handle handle; auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer); sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly); encoder << SharedMemory::IPCHandle { WTFMove(handle), bufferSize }; #endif } static WARN_UNUSED_RETURN bool decodeSharedBuffer(Decoder& decoder, RefPtr& buffer) { std::optional isNull; decoder >> isNull; if (!isNull) return false; if (*isNull) { buffer = nullptr; return true; } uint64_t bufferSize = 0; if (!decoder.decode(bufferSize)) return false; if (!bufferSize) { buffer = SharedBuffer::create(); return true; } #if USE(UNIX_DOMAIN_SOCKETS) if (!decoder.bufferIsLargeEnoughToContain(bufferSize)) return false; Vector data; data.grow(bufferSize); if (!decoder.decodeFixedLengthData(data.data(), data.size(), 1)) return false; buffer = SharedBuffer::create(WTFMove(data)); #else SharedMemory::IPCHandle ipcHandle; if (!decoder.decode(ipcHandle)) return false; auto sharedMemoryBuffer = SharedMemory::map(ipcHandle.handle, SharedMemory::Protection::ReadOnly); if (!sharedMemoryBuffer) return false; if (sharedMemoryBuffer->size() < bufferSize) return false; buffer = SharedBuffer::create(static_cast(sharedMemoryBuffer->data()), bufferSize); #endif return true; } static void encodeTypesAndData(Encoder& encoder, const Vector& types, const Vector>& data) { ASSERT(types.size() == data.size()); encoder << types; encoder << static_cast(data.size()); for (auto& buffer : data) encodeSharedBuffer(encoder, buffer.get()); } static WARN_UNUSED_RETURN bool decodeTypesAndData(Decoder& decoder, Vector& types, Vector>& data) { if (!decoder.decode(types)) return false; uint64_t dataSize; if (!decoder.decode(dataSize)) return false; ASSERT(dataSize == types.size()); for (uint64_t i = 0; i < dataSize; i++) { RefPtr buffer; if (!decodeSharedBuffer(decoder, buffer)) return false; data.append(WTFMove(buffer)); } return true; } void ArgumentCoder::encode(Encoder& encoder, const AffineTransform& affineTransform) { SimpleArgumentCoder::encode(encoder, affineTransform); } bool ArgumentCoder::decode(Decoder& decoder, AffineTransform& affineTransform) { return SimpleArgumentCoder::decode(decoder, affineTransform); } void ArgumentCoder::encode(Encoder& encoder, const CacheQueryOptions& options) { encoder << options.ignoreSearch; encoder << options.ignoreMethod; encoder << options.ignoreVary; encoder << options.cacheName; } bool ArgumentCoder::decode(Decoder& decoder, CacheQueryOptions& options) { bool ignoreSearch; if (!decoder.decode(ignoreSearch)) return false; bool ignoreMethod; if (!decoder.decode(ignoreMethod)) return false; bool ignoreVary; if (!decoder.decode(ignoreVary)) return false; String cacheName; if (!decoder.decode(cacheName)) return false; options.ignoreSearch = ignoreSearch; options.ignoreMethod = ignoreMethod; options.ignoreVary = ignoreVary; options.cacheName = WTFMove(cacheName); return true; } void ArgumentCoder::encode(Encoder& encoder, const CharacterRange& range) { encoder << static_cast(range.location); encoder << static_cast(range.length); } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional location; decoder >> location; if (!location) return std::nullopt; std::optional length; decoder >> length; if (!length) return std::nullopt; return { { *location, *length } }; } void ArgumentCoder::encode(Encoder& encoder, const DOMCacheEngine::CacheInfo& info) { encoder << info.identifier; encoder << info.name; } auto ArgumentCoder::decode(Decoder& decoder) -> std::optional { std::optional identifier; decoder >> identifier; if (!identifier) return std::nullopt; std::optional name; decoder >> name; if (!name) return std::nullopt; return {{ WTFMove(*identifier), WTFMove(*name) }}; } void ArgumentCoder::encode(Encoder& encoder, const DOMCacheEngine::Record& record) { encoder << record.identifier; encoder << record.requestHeadersGuard; encoder << record.request; encoder << record.options; encoder << record.referrer; encoder << record.responseHeadersGuard; encoder << record.response; encoder << record.updateResponseCounter; encoder << record.responseBodySize; WTF::switchOn(record.responseBody, [&](const Ref& buffer) { encoder << true; encodeSharedBuffer(encoder, buffer.ptr()); }, [&](const Ref& formData) { encoder << false; encoder << true; formData->encode(encoder); }, [&](const std::nullptr_t&) { encoder << false; encoder << false; }); } std::optional ArgumentCoder::decode(Decoder& decoder) { uint64_t identifier; if (!decoder.decode(identifier)) return std::nullopt; FetchHeaders::Guard requestHeadersGuard; if (!decoder.decode(requestHeadersGuard)) return std::nullopt; WebCore::ResourceRequest request; if (!decoder.decode(request)) return std::nullopt; std::optional options; decoder >> options; if (!options) return std::nullopt; String referrer; if (!decoder.decode(referrer)) return std::nullopt; FetchHeaders::Guard responseHeadersGuard; if (!decoder.decode(responseHeadersGuard)) return std::nullopt; WebCore::ResourceResponse response; if (!decoder.decode(response)) return std::nullopt; uint64_t updateResponseCounter; if (!decoder.decode(updateResponseCounter)) return std::nullopt; uint64_t responseBodySize; if (!decoder.decode(responseBodySize)) return std::nullopt; WebCore::DOMCacheEngine::ResponseBody responseBody; bool hasSharedBufferBody; if (!decoder.decode(hasSharedBufferBody)) return std::nullopt; if (hasSharedBufferBody) { RefPtr buffer; if (!decodeSharedBuffer(decoder, buffer)) return std::nullopt; if (buffer) responseBody = buffer.releaseNonNull(); } else { bool hasFormDataBody; if (!decoder.decode(hasFormDataBody)) return std::nullopt; if (hasFormDataBody) { auto formData = FormData::decode(decoder); if (!formData) return std::nullopt; responseBody = formData.releaseNonNull(); } } return {{ WTFMove(identifier), WTFMove(updateResponseCounter), WTFMove(requestHeadersGuard), WTFMove(request), WTFMove(options.value()), WTFMove(referrer), WTFMove(responseHeadersGuard), WTFMove(response), WTFMove(responseBody), responseBodySize }}; } void ArgumentCoder::encode(Encoder& encoder, const EventTrackingRegions& eventTrackingRegions) { encoder << eventTrackingRegions.asynchronousDispatchRegion; encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions; } bool ArgumentCoder::decode(Decoder& decoder, EventTrackingRegions& eventTrackingRegions) { std::optional asynchronousDispatchRegion; decoder >> asynchronousDispatchRegion; if (!asynchronousDispatchRegion) return false; HashMap eventSpecificSynchronousDispatchRegions; if (!decoder.decode(eventSpecificSynchronousDispatchRegions)) return false; eventTrackingRegions.asynchronousDispatchRegion = WTFMove(*asynchronousDispatchRegion); eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions); return true; } void ArgumentCoder::encode(Encoder& encoder, const TransformationMatrix& transformationMatrix) { encoder << transformationMatrix.m11(); encoder << transformationMatrix.m12(); encoder << transformationMatrix.m13(); encoder << transformationMatrix.m14(); encoder << transformationMatrix.m21(); encoder << transformationMatrix.m22(); encoder << transformationMatrix.m23(); encoder << transformationMatrix.m24(); encoder << transformationMatrix.m31(); encoder << transformationMatrix.m32(); encoder << transformationMatrix.m33(); encoder << transformationMatrix.m34(); encoder << transformationMatrix.m41(); encoder << transformationMatrix.m42(); encoder << transformationMatrix.m43(); encoder << transformationMatrix.m44(); } bool ArgumentCoder::decode(Decoder& decoder, TransformationMatrix& transformationMatrix) { double m11; if (!decoder.decode(m11)) return false; double m12; if (!decoder.decode(m12)) return false; double m13; if (!decoder.decode(m13)) return false; double m14; if (!decoder.decode(m14)) return false; double m21; if (!decoder.decode(m21)) return false; double m22; if (!decoder.decode(m22)) return false; double m23; if (!decoder.decode(m23)) return false; double m24; if (!decoder.decode(m24)) return false; double m31; if (!decoder.decode(m31)) return false; double m32; if (!decoder.decode(m32)) return false; double m33; if (!decoder.decode(m33)) return false; double m34; if (!decoder.decode(m34)) return false; double m41; if (!decoder.decode(m41)) return false; double m42; if (!decoder.decode(m42)) return false; double m43; if (!decoder.decode(m43)) return false; double m44; if (!decoder.decode(m44)) return false; transformationMatrix.setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); return true; } void ArgumentCoder::encode(Encoder& encoder, const LinearTimingFunction& timingFunction) { encoder << timingFunction.type(); } bool ArgumentCoder::decode(Decoder&, LinearTimingFunction&) { // Type is decoded by the caller. Nothing else to decode. return true; } void ArgumentCoder::encode(Encoder& encoder, const CubicBezierTimingFunction& timingFunction) { encoder << timingFunction.type(); encoder << timingFunction.x1(); encoder << timingFunction.y1(); encoder << timingFunction.x2(); encoder << timingFunction.y2(); encoder << timingFunction.timingFunctionPreset(); } bool ArgumentCoder::decode(Decoder& decoder, CubicBezierTimingFunction& timingFunction) { // Type is decoded by the caller. double x1; if (!decoder.decode(x1)) return false; double y1; if (!decoder.decode(y1)) return false; double x2; if (!decoder.decode(x2)) return false; double y2; if (!decoder.decode(y2)) return false; CubicBezierTimingFunction::TimingFunctionPreset preset; if (!decoder.decode(preset)) return false; timingFunction.setValues(x1, y1, x2, y2); timingFunction.setTimingFunctionPreset(preset); return true; } void ArgumentCoder::encode(Encoder& encoder, const StepsTimingFunction& timingFunction) { encoder << timingFunction.type(); encoder << timingFunction.numberOfSteps(); encoder << timingFunction.stepPosition(); } bool ArgumentCoder::decode(Decoder& decoder, StepsTimingFunction& timingFunction) { // Type is decoded by the caller. int numSteps; if (!decoder.decode(numSteps)) return false; std::optional stepPosition; if (!decoder.decode(stepPosition)) return false; timingFunction.setNumberOfSteps(numSteps); timingFunction.setStepPosition(stepPosition); return true; } void ArgumentCoder::encode(Encoder& encoder, const SpringTimingFunction& timingFunction) { encoder << timingFunction.type(); encoder << timingFunction.mass(); encoder << timingFunction.stiffness(); encoder << timingFunction.damping(); encoder << timingFunction.initialVelocity(); } bool ArgumentCoder::decode(Decoder& decoder, SpringTimingFunction& timingFunction) { // Type is decoded by the caller. double mass; if (!decoder.decode(mass)) return false; double stiffness; if (!decoder.decode(stiffness)) return false; double damping; if (!decoder.decode(damping)) return false; double initialVelocity; if (!decoder.decode(initialVelocity)) return false; timingFunction.setValues(mass, stiffness, damping, initialVelocity); return true; } void ArgumentCoder::encode(Encoder& encoder, const FloatPoint& floatPoint) { SimpleArgumentCoder::encode(encoder, floatPoint); } bool ArgumentCoder::decode(Decoder& decoder, FloatPoint& floatPoint) { return SimpleArgumentCoder::decode(decoder, floatPoint); } std::optional ArgumentCoder::decode(Decoder& decoder) { FloatPoint floatPoint; if (!SimpleArgumentCoder::decode(decoder, floatPoint)) return std::nullopt; return floatPoint; } void ArgumentCoder::encode(Encoder& encoder, const FloatPoint3D& floatPoint) { SimpleArgumentCoder::encode(encoder, floatPoint); } bool ArgumentCoder::decode(Decoder& decoder, FloatPoint3D& floatPoint) { return SimpleArgumentCoder::decode(decoder, floatPoint); } void ArgumentCoder::encode(Encoder& encoder, const FloatRect& floatRect) { SimpleArgumentCoder::encode(encoder, floatRect); } bool ArgumentCoder::decode(Decoder& decoder, FloatRect& floatRect) { return SimpleArgumentCoder::decode(decoder, floatRect); } std::optional ArgumentCoder::decode(Decoder& decoder) { FloatRect floatRect; if (!SimpleArgumentCoder::decode(decoder, floatRect)) return std::nullopt; return floatRect; } void ArgumentCoder::encode(Encoder& encoder, const FloatBoxExtent& floatBoxExtent) { SimpleArgumentCoder::encode(encoder, floatBoxExtent); } bool ArgumentCoder::decode(Decoder& decoder, FloatBoxExtent& floatBoxExtent) { return SimpleArgumentCoder::decode(decoder, floatBoxExtent); } void ArgumentCoder::encode(Encoder& encoder, const FloatSize& floatSize) { SimpleArgumentCoder::encode(encoder, floatSize); } bool ArgumentCoder::decode(Decoder& decoder, FloatSize& floatSize) { return SimpleArgumentCoder::decode(decoder, floatSize); } void ArgumentCoder::encode(Encoder& encoder, const FloatRoundedRect& roundedRect) { SimpleArgumentCoder::encode(encoder, roundedRect); } bool ArgumentCoder::decode(Decoder& decoder, FloatRoundedRect& roundedRect) { return SimpleArgumentCoder::decode(decoder, roundedRect); } #if ENABLE(META_VIEWPORT) void ArgumentCoder::encode(Encoder& encoder, const ViewportArguments& viewportArguments) { SimpleArgumentCoder::encode(encoder, viewportArguments); } bool ArgumentCoder::decode(Decoder& decoder, ViewportArguments& viewportArguments) { return SimpleArgumentCoder::decode(decoder, viewportArguments); } std::optional ArgumentCoder::decode(Decoder& decoder) { ViewportArguments viewportArguments; if (!SimpleArgumentCoder::decode(decoder, viewportArguments)) return std::nullopt; return viewportArguments; } #endif // ENABLE(META_VIEWPORT) void ArgumentCoder::encode(Encoder& encoder, const ViewportAttributes& viewportAttributes) { SimpleArgumentCoder::encode(encoder, viewportAttributes); } bool ArgumentCoder::decode(Decoder& decoder, ViewportAttributes& viewportAttributes) { return SimpleArgumentCoder::decode(decoder, viewportAttributes); } void ArgumentCoder::encode(Encoder& encoder, const IntPoint& intPoint) { SimpleArgumentCoder::encode(encoder, intPoint); } bool ArgumentCoder::decode(Decoder& decoder, IntPoint& intPoint) { return SimpleArgumentCoder::decode(decoder, intPoint); } std::optional ArgumentCoder::decode(Decoder& decoder) { IntPoint intPoint; if (!SimpleArgumentCoder::decode(decoder, intPoint)) return std::nullopt; return intPoint; } void ArgumentCoder::encode(Encoder& encoder, const IntRect& intRect) { SimpleArgumentCoder::encode(encoder, intRect); } bool ArgumentCoder::decode(Decoder& decoder, IntRect& intRect) { return SimpleArgumentCoder::decode(decoder, intRect); } std::optional ArgumentCoder::decode(Decoder& decoder) { IntRect rect; if (!decode(decoder, rect)) return std::nullopt; return rect; } template void ArgumentCoder::encode(Encoder& encoder, const IntSize& intSize) { SimpleArgumentCoder::encode(encoder, intSize); } template void ArgumentCoder::encode(Encoder&, const IntSize&); template void ArgumentCoder::encode(StreamConnectionEncoder&, const IntSize&); bool ArgumentCoder::decode(Decoder& decoder, IntSize& intSize) { return SimpleArgumentCoder::decode(decoder, intSize); } std::optional ArgumentCoder::decode(Decoder& decoder) { IntSize intSize; if (!SimpleArgumentCoder::decode(decoder, intSize)) return std::nullopt; return intSize; } void ArgumentCoder::encode(Encoder& encoder, const LayoutSize& layoutSize) { SimpleArgumentCoder::encode(encoder, layoutSize); } bool ArgumentCoder::decode(Decoder& decoder, LayoutSize& layoutSize) { return SimpleArgumentCoder::decode(decoder, layoutSize); } void ArgumentCoder::encode(Encoder& encoder, const LayoutPoint& layoutPoint) { SimpleArgumentCoder::encode(encoder, layoutPoint); } bool ArgumentCoder::decode(Decoder& decoder, LayoutPoint& layoutPoint) { return SimpleArgumentCoder::decode(decoder, layoutPoint); } void ArgumentCoder::encode(Encoder& encoder, const RecentSearch& recentSearch) { encoder << recentSearch.string << recentSearch.time; } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional string; decoder >> string; if (!string) return std::nullopt; std::optional time; decoder >> time; if (!time) return std::nullopt; return {{ WTFMove(*string), WTFMove(*time) }}; } void ArgumentCoder::encode(Encoder& encoder, const Length& length) { SimpleArgumentCoder::encode(encoder, length); } bool ArgumentCoder::decode(Decoder& decoder, Length& length) { return SimpleArgumentCoder::decode(decoder, length); } void ArgumentCoder::encode(Encoder& encoder, const VelocityData& velocityData) { encoder << velocityData.horizontalVelocity << velocityData.verticalVelocity << velocityData.scaleChangeRate << velocityData.lastUpdateTime; } bool ArgumentCoder::decode(Decoder& decoder, VelocityData& velocityData) { float horizontalVelocity; if (!decoder.decode(horizontalVelocity)) return false; float verticalVelocity; if (!decoder.decode(verticalVelocity)) return false; float scaleChangeRate; if (!decoder.decode(scaleChangeRate)) return false; MonotonicTime lastUpdateTime; if (!decoder.decode(lastUpdateTime)) return false; velocityData.horizontalVelocity = horizontalVelocity; velocityData.verticalVelocity = verticalVelocity; velocityData.scaleChangeRate = scaleChangeRate; velocityData.lastUpdateTime = lastUpdateTime; return true; } void ArgumentCoder::encode(Encoder& encoder, const MimeClassInfo& mimeClassInfo) { encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions; } std::optional ArgumentCoder::decode(Decoder& decoder) { MimeClassInfo mimeClassInfo; if (!decoder.decode(mimeClassInfo.type)) return std::nullopt; if (!decoder.decode(mimeClassInfo.desc)) return std::nullopt; if (!decoder.decode(mimeClassInfo.extensions)) return std::nullopt; return mimeClassInfo; } void ArgumentCoder::encode(Encoder& encoder, const PluginInfo& pluginInfo) { encoder << pluginInfo.name; encoder << pluginInfo.file; encoder << pluginInfo.desc; encoder << pluginInfo.mimes; encoder << pluginInfo.isApplicationPlugin; encoder << pluginInfo.clientLoadPolicy; encoder << pluginInfo.bundleIdentifier; #if PLATFORM(MAC) encoder << pluginInfo.versionString; #endif } std::optional ArgumentCoder::decode(Decoder& decoder) { PluginInfo pluginInfo; if (!decoder.decode(pluginInfo.name)) return std::nullopt; if (!decoder.decode(pluginInfo.file)) return std::nullopt; if (!decoder.decode(pluginInfo.desc)) return std::nullopt; if (!decoder.decode(pluginInfo.mimes)) return std::nullopt; if (!decoder.decode(pluginInfo.isApplicationPlugin)) return std::nullopt; if (!decoder.decode(pluginInfo.clientLoadPolicy)) return std::nullopt; if (!decoder.decode(pluginInfo.bundleIdentifier)) return std::nullopt; #if PLATFORM(MAC) if (!decoder.decode(pluginInfo.versionString)) return std::nullopt; #endif return pluginInfo; } void ArgumentCoder::encode(Encoder& encoder, const AuthenticationChallenge& challenge) { encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error(); #if USE(SOUP) encoder << challenge.tlsPasswordFlags(); #endif } bool ArgumentCoder::decode(Decoder& decoder, AuthenticationChallenge& challenge) { ProtectionSpace protectionSpace; if (!decoder.decode(protectionSpace)) return false; Credential proposedCredential; if (!decoder.decode(proposedCredential)) return false; unsigned previousFailureCount; if (!decoder.decode(previousFailureCount)) return false; ResourceResponse failureResponse; if (!decoder.decode(failureResponse)) return false; ResourceError error; if (!decoder.decode(error)) return false; #if USE(SOUP) uint32_t tlsPasswordFlags; if (!decoder.decode(tlsPasswordFlags)) return false; #endif challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error); #if USE(SOUP) challenge.setTLSPasswordFlags(tlsPasswordFlags); #endif return true; } void ArgumentCoder::encode(Encoder& encoder, const ProtectionSpace& space) { if (space.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, space); return; } encoder << false; encoder << space.host() << space.port() << space.realm(); encoder << space.authenticationScheme(); encoder << space.serverType(); } bool ArgumentCoder::decode(Decoder& decoder, ProtectionSpace& space) { bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, space); String host; if (!decoder.decode(host)) return false; int port; if (!decoder.decode(port)) return false; String realm; if (!decoder.decode(realm)) return false; ProtectionSpaceAuthenticationScheme authenticationScheme; if (!decoder.decode(authenticationScheme)) return false; ProtectionSpaceServerType serverType; if (!decoder.decode(serverType)) return false; space = ProtectionSpace(host, port, serverType, realm, authenticationScheme); return true; } void ArgumentCoder::encode(Encoder& encoder, const Credential& credential) { if (credential.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, credential); return; } encoder << false; encoder << credential.user() << credential.password(); encoder << credential.persistence(); } bool ArgumentCoder::decode(Decoder& decoder, Credential& credential) { bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, credential); String user; if (!decoder.decode(user)) return false; String password; if (!decoder.decode(password)) return false; CredentialPersistence persistence; if (!decoder.decode(persistence)) return false; credential = Credential(user, password, persistence); return true; } static void encodeImage(Encoder& encoder, Image& image) { RefPtr bitmap = ShareableBitmap::createShareable(IntSize(image.size()), { }); auto graphicsContext = bitmap->createGraphicsContext(); encoder << !!graphicsContext; if (!graphicsContext) return; graphicsContext->drawImage(image, IntPoint()); ShareableBitmap::Handle handle; bitmap->createHandle(handle); encoder << handle; } static WARN_UNUSED_RETURN bool decodeImage(Decoder& decoder, RefPtr& image) { std::optional didCreateGraphicsContext; decoder >> didCreateGraphicsContext; if (!didCreateGraphicsContext || !*didCreateGraphicsContext) return false; ShareableBitmap::Handle handle; if (!decoder.decode(handle)) return false; RefPtr bitmap = ShareableBitmap::create(handle); if (!bitmap) return false; image = bitmap->createImage(); if (!image) return false; return true; } static void encodeOptionalImage(Encoder& encoder, Image* image) { bool hasImage = !!image; encoder << hasImage; if (hasImage) encodeImage(encoder, *image); } static WARN_UNUSED_RETURN bool decodeOptionalImage(Decoder& decoder, RefPtr& image) { image = nullptr; bool hasImage; if (!decoder.decode(hasImage)) return false; if (!hasImage) return true; return decodeImage(decoder, image); } void ArgumentCoder>::encode(Encoder& encoder, const Ref& font) { encoder << font->origin(); encoder << (font->isInterstitial() ? Font::Interstitial::Yes : Font::Interstitial::No); encoder << font->visibility(); encoder << (font->isTextOrientationFallback() ? Font::OrientationFallback::Yes : Font::OrientationFallback::No); encoder << font->renderingResourceIdentifier(); // Intentionally don't encode m_isBrokenIdeographFallback because it doesn't affect drawGlyphs(). encodePlatformData(encoder, font); } std::optional> ArgumentCoder>::decode(Decoder& decoder) { std::optional origin; decoder >> origin; if (!origin) return std::nullopt; std::optional isInterstitial; decoder >> isInterstitial; if (!isInterstitial) return std::nullopt; std::optional visibility; decoder >> visibility; if (!visibility) return std::nullopt; std::optional isTextOrientationFallback; decoder >> isTextOrientationFallback; if (!isTextOrientationFallback) return std::nullopt; std::optional renderingRersouceIdentifier; decoder >> renderingRersouceIdentifier; if (!renderingRersouceIdentifier) return std::nullopt; auto platformData = decodePlatformData(decoder); if (!platformData) return std::nullopt; return Font::create(platformData.value(), origin.value(), isInterstitial.value(), visibility.value(), isTextOrientationFallback.value(), renderingRersouceIdentifier); } void ArgumentCoder::encode(Encoder& encoder, const Cursor& cursor) { encoder << cursor.type(); if (cursor.type() != Cursor::Custom) return; if (cursor.image()->isNull()) { encoder << false; // There is no valid image being encoded. return; } encoder << true; encodeImage(encoder, *cursor.image()); encoder << cursor.hotSpot(); #if ENABLE(MOUSE_CURSOR_SCALE) encoder << cursor.imageScaleFactor(); #endif } bool ArgumentCoder::decode(Decoder& decoder, Cursor& cursor) { Cursor::Type type; if (!decoder.decode(type)) return false; if (type > Cursor::Custom) return false; if (type != Cursor::Custom) { const Cursor& cursorReference = Cursor::fromType(type); // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore. // This will avoid having to re-create the platform cursors over and over. (void)cursorReference.platformCursor(); cursor = cursorReference; return true; } bool isValidImagePresent; if (!decoder.decode(isValidImagePresent)) return false; if (!isValidImagePresent) { cursor = Cursor(&Image::nullImage(), IntPoint()); return true; } RefPtr image; if (!decodeImage(decoder, image)) return false; IntPoint hotSpot; if (!decoder.decode(hotSpot)) return false; if (!image->rect().contains(hotSpot)) return false; #if ENABLE(MOUSE_CURSOR_SCALE) float scale; if (!decoder.decode(scale)) return false; cursor = Cursor(image.get(), hotSpot, scale); #else cursor = Cursor(image.get(), hotSpot); #endif return true; } void ArgumentCoder::encode(Encoder& encoder, const ResourceRequest& resourceRequest) { encoder << resourceRequest.cachePartition(); encoder << resourceRequest.hiddenFromInspector(); #if USE(SYSTEM_PREVIEW) if (resourceRequest.isSystemPreview()) { encoder << true; encoder << resourceRequest.systemPreviewInfo(); } else encoder << false; #endif if (resourceRequest.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, resourceRequest); return; } encoder << false; resourceRequest.encodeWithoutPlatformData(encoder); } bool ArgumentCoder::decode(Decoder& decoder, ResourceRequest& resourceRequest) { String cachePartition; if (!decoder.decode(cachePartition)) return false; resourceRequest.setCachePartition(cachePartition); bool isHiddenFromInspector; if (!decoder.decode(isHiddenFromInspector)) return false; resourceRequest.setHiddenFromInspector(isHiddenFromInspector); #if USE(SYSTEM_PREVIEW) bool isSystemPreview; if (!decoder.decode(isSystemPreview)) return false; if (isSystemPreview) { SystemPreviewInfo systemPreviewInfo; if (!decoder.decode(systemPreviewInfo)) return false; resourceRequest.setSystemPreviewInfo(systemPreviewInfo); } #endif bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, resourceRequest); return resourceRequest.decodeWithoutPlatformData(decoder); } void ArgumentCoder::encode(Encoder& encoder, const ResourceError& resourceError) { encoder << resourceError.type(); if (resourceError.type() == ResourceError::Type::Null) return; encodePlatformData(encoder, resourceError); encoder << resourceError.isSanitized(); } bool ArgumentCoder::decode(Decoder& decoder, ResourceError& resourceError) { ResourceError::Type type; if (!decoder.decode(type)) return false; if (type == ResourceError::Type::Null) { resourceError = { }; return true; } if (!decodePlatformData(decoder, resourceError)) return false; bool isSanitized; if (!decoder.decode(isSanitized)) return false; resourceError.setType(type); if (isSanitized) resourceError.setAsSanitized(); return true; } #if PLATFORM(IOS_FAMILY) void ArgumentCoder::encode(Encoder& encoder, const SelectionGeometry& selectionGeometry) { encoder << selectionGeometry.quad(); encoder << selectionGeometry.behavior(); encoder << static_cast(selectionGeometry.direction()); encoder << selectionGeometry.minX(); encoder << selectionGeometry.maxX(); encoder << selectionGeometry.maxY(); encoder << selectionGeometry.lineNumber(); encoder << selectionGeometry.isLineBreak(); encoder << selectionGeometry.isFirstOnLine(); encoder << selectionGeometry.isLastOnLine(); encoder << selectionGeometry.containsStart(); encoder << selectionGeometry.containsEnd(); encoder << selectionGeometry.isHorizontal(); } std::optional ArgumentCoder::decode(Decoder& decoder) { SelectionGeometry selectionGeometry; FloatQuad quad; if (!decoder.decode(quad)) return std::nullopt; selectionGeometry.setQuad(quad); std::optional behavior; decoder >> behavior; if (!behavior) return std::nullopt; selectionGeometry.setBehavior(*behavior); uint32_t direction; if (!decoder.decode(direction)) return std::nullopt; selectionGeometry.setDirection((TextDirection)direction); int intValue; if (!decoder.decode(intValue)) return std::nullopt; selectionGeometry.setMinX(intValue); if (!decoder.decode(intValue)) return std::nullopt; selectionGeometry.setMaxX(intValue); if (!decoder.decode(intValue)) return std::nullopt; selectionGeometry.setMaxY(intValue); if (!decoder.decode(intValue)) return std::nullopt; selectionGeometry.setLineNumber(intValue); bool boolValue; if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setIsLineBreak(boolValue); if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setIsFirstOnLine(boolValue); if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setIsLastOnLine(boolValue); if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setContainsStart(boolValue); if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setContainsEnd(boolValue); if (!decoder.decode(boolValue)) return std::nullopt; selectionGeometry.setIsHorizontal(boolValue); return selectionGeometry; } #endif void ArgumentCoder::encode(Encoder& encoder, const WindowFeatures& windowFeatures) { encoder << windowFeatures.x; encoder << windowFeatures.y; encoder << windowFeatures.width; encoder << windowFeatures.height; encoder << windowFeatures.menuBarVisible; encoder << windowFeatures.statusBarVisible; encoder << windowFeatures.toolBarVisible; encoder << windowFeatures.locationBarVisible; encoder << windowFeatures.scrollbarsVisible; encoder << windowFeatures.resizable; encoder << windowFeatures.fullscreen; encoder << windowFeatures.dialog; } bool ArgumentCoder::decode(Decoder& decoder, WindowFeatures& windowFeatures) { if (!decoder.decode(windowFeatures.x)) return false; if (!decoder.decode(windowFeatures.y)) return false; if (!decoder.decode(windowFeatures.width)) return false; if (!decoder.decode(windowFeatures.height)) return false; if (!decoder.decode(windowFeatures.menuBarVisible)) return false; if (!decoder.decode(windowFeatures.statusBarVisible)) return false; if (!decoder.decode(windowFeatures.toolBarVisible)) return false; if (!decoder.decode(windowFeatures.locationBarVisible)) return false; if (!decoder.decode(windowFeatures.scrollbarsVisible)) return false; if (!decoder.decode(windowFeatures.resizable)) return false; if (!decoder.decode(windowFeatures.fullscreen)) return false; if (!decoder.decode(windowFeatures.dialog)) return false; return true; } #if ENABLE(DRAG_SUPPORT) void ArgumentCoder::encode(Encoder& encoder, const DragData& dragData) { encoder << dragData.clientPosition(); encoder << dragData.globalPosition(); encoder << dragData.draggingSourceOperationMask(); encoder << dragData.flags(); #if PLATFORM(COCOA) encoder << dragData.pasteboardName(); encoder << dragData.fileNames(); #endif encoder << dragData.dragDestinationActionMask(); encoder << dragData.pageID(); } bool ArgumentCoder::decode(Decoder& decoder, DragData& dragData) { IntPoint clientPosition; if (!decoder.decode(clientPosition)) return false; IntPoint globalPosition; if (!decoder.decode(globalPosition)) return false; OptionSet draggingSourceOperationMask; if (!decoder.decode(draggingSourceOperationMask)) return false; OptionSet applicationFlags; if (!decoder.decode(applicationFlags)) return false; String pasteboardName; Vector fileNames; #if PLATFORM(COCOA) if (!decoder.decode(pasteboardName)) return false; if (!decoder.decode(fileNames)) return false; #endif OptionSet dragDestinationActionMask; if (!decoder.decode(dragDestinationActionMask)) return false; std::optional pageID; if (!decoder.decode(pageID)) return false; dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, dragDestinationActionMask, pageID); dragData.setFileNames(fileNames); return true; } #endif void ArgumentCoder::encode(Encoder& encoder, const CompositionUnderline& underline) { encoder << underline.startOffset; encoder << underline.endOffset; encoder << underline.thick; encoder << underline.compositionUnderlineColor; encoder << underline.color; } std::optional ArgumentCoder::decode(Decoder& decoder) { CompositionUnderline underline; if (!decoder.decode(underline.startOffset)) return std::nullopt; if (!decoder.decode(underline.endOffset)) return std::nullopt; if (!decoder.decode(underline.thick)) return std::nullopt; if (!decoder.decode(underline.compositionUnderlineColor)) return std::nullopt; if (!decoder.decode(underline.color)) return std::nullopt; return underline; } void ArgumentCoder::encode(Encoder& encoder, const DatabaseDetails& details) { encoder << details.name(); encoder << details.displayName(); encoder << details.expectedUsage(); encoder << details.currentUsage(); encoder << details.creationTime(); encoder << details.modificationTime(); } bool ArgumentCoder::decode(Decoder& decoder, DatabaseDetails& details) { String name; if (!decoder.decode(name)) return false; String displayName; if (!decoder.decode(displayName)) return false; uint64_t expectedUsage; if (!decoder.decode(expectedUsage)) return false; uint64_t currentUsage; if (!decoder.decode(currentUsage)) return false; std::optional creationTime; if (!decoder.decode(creationTime)) return false; std::optional modificationTime; if (!decoder.decode(modificationTime)) return false; details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime); return true; } template<> struct ArgumentCoder { static void encode(Encoder&, const PasteboardCustomData::Entry&); static WARN_UNUSED_RETURN bool decode(Decoder&, PasteboardCustomData::Entry&); }; void ArgumentCoder::encode(Encoder& encoder, const PasteboardCustomData::Entry& data) { encoder << data.type << data.customData; auto& platformData = data.platformData; bool hasString = WTF::holds_alternative(platformData); encoder << hasString; if (hasString) encoder << WTF::get(platformData); bool hasBuffer = WTF::holds_alternative>(platformData); encoder << hasBuffer; if (hasBuffer) encodeSharedBuffer(encoder, WTF::get>(platformData).ptr()); } bool ArgumentCoder::decode(Decoder& decoder, PasteboardCustomData::Entry& data) { if (!decoder.decode(data.type)) return false; if (!decoder.decode(data.customData)) return false; bool hasString; if (!decoder.decode(hasString)) return false; if (hasString) { String value; if (!decoder.decode(value)) return false; data.platformData = { WTFMove(value) }; } bool hasBuffer; if (!decoder.decode(hasBuffer)) return false; if (hasString && hasBuffer) return false; if (hasBuffer) { RefPtr value; if (!decodeSharedBuffer(decoder, value) || !value) return false; data.platformData = { value.releaseNonNull() }; } return true; } void ArgumentCoder::encode(Encoder& encoder, const PasteboardCustomData& data) { encoder << data.origin(); encoder << data.data(); } bool ArgumentCoder::decode(Decoder& decoder, PasteboardCustomData& data) { String origin; if (!decoder.decode(origin)) return false; Vector items; if (!decoder.decode(items)) return false; data = PasteboardCustomData(WTFMove(origin), WTFMove(items)); return true; } void ArgumentCoder::encode(Encoder& encoder, const PasteboardURL& content) { encoder << content.url; encoder << content.title; #if PLATFORM(MAC) encoder << content.userVisibleForm; #endif #if PLATFORM(GTK) encoder << content.markup; #endif } bool ArgumentCoder::decode(Decoder& decoder, PasteboardURL& content) { if (!decoder.decode(content.url)) return false; if (!decoder.decode(content.title)) return false; #if PLATFORM(MAC) if (!decoder.decode(content.userVisibleForm)) return false; #endif #if PLATFORM(GTK) if (!decoder.decode(content.markup)) return false; #endif return true; } #if PLATFORM(IOS_FAMILY) void ArgumentCoder::encode(Encoder& encoder, const InspectorOverlay::Highlight& highlight) { encoder << static_cast(highlight.type); encoder << highlight.usePageCoordinates; encoder << highlight.contentColor; encoder << highlight.contentOutlineColor; encoder << highlight.paddingColor; encoder << highlight.borderColor; encoder << highlight.marginColor; encoder << highlight.quads; encoder << highlight.gridHighlightOverlays; } bool ArgumentCoder::decode(Decoder& decoder, InspectorOverlay::Highlight& highlight) { uint32_t type; if (!decoder.decode(type)) return false; highlight.type = (InspectorOverlay::Highlight::Type)type; if (!decoder.decode(highlight.usePageCoordinates)) return false; if (!decoder.decode(highlight.contentColor)) return false; if (!decoder.decode(highlight.contentOutlineColor)) return false; if (!decoder.decode(highlight.paddingColor)) return false; if (!decoder.decode(highlight.borderColor)) return false; if (!decoder.decode(highlight.marginColor)) return false; if (!decoder.decode(highlight.quads)) return false; if (!decoder.decode(highlight.gridHighlightOverlays)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const PasteboardWebContent& content) { encoder << content.contentOrigin; encoder << content.canSmartCopyOrDelete; encoder << content.dataInStringFormat; encoder << content.dataInHTMLFormat; encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get()); encodeSharedBuffer(encoder, content.dataInRTFDFormat.get()); encodeSharedBuffer(encoder, content.dataInRTFFormat.get()); encodeSharedBuffer(encoder, content.dataInAttributedStringFormat.get()); encodeTypesAndData(encoder, content.clientTypes, content.clientData); } bool ArgumentCoder::decode(Decoder& decoder, PasteboardWebContent& content) { if (!decoder.decode(content.contentOrigin)) return false; if (!decoder.decode(content.canSmartCopyOrDelete)) return false; if (!decoder.decode(content.dataInStringFormat)) return false; if (!decoder.decode(content.dataInHTMLFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInRTFFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInAttributedStringFormat)) return false; if (!decodeTypesAndData(decoder, content.clientTypes, content.clientData)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const PasteboardImage& pasteboardImage) { encodeOptionalImage(encoder, pasteboardImage.image.get()); encoder << pasteboardImage.url.url; encoder << pasteboardImage.url.title; encoder << pasteboardImage.resourceMIMEType; encoder << pasteboardImage.suggestedName; encoder << pasteboardImage.imageSize; if (pasteboardImage.resourceData) encodeSharedBuffer(encoder, pasteboardImage.resourceData.get()); encodeTypesAndData(encoder, pasteboardImage.clientTypes, pasteboardImage.clientData); } bool ArgumentCoder::decode(Decoder& decoder, PasteboardImage& pasteboardImage) { if (!decodeOptionalImage(decoder, pasteboardImage.image)) return false; if (!decoder.decode(pasteboardImage.url.url)) return false; if (!decoder.decode(pasteboardImage.url.title)) return false; if (!decoder.decode(pasteboardImage.resourceMIMEType)) return false; if (!decoder.decode(pasteboardImage.suggestedName)) return false; if (!decoder.decode(pasteboardImage.imageSize)) return false; if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData)) return false; if (!decodeTypesAndData(decoder, pasteboardImage.clientTypes, pasteboardImage.clientData)) return false; return true; } #endif #if USE(LIBWPE) void ArgumentCoder::encode(Encoder& encoder, const PasteboardWebContent& content) { encoder << content.text; encoder << content.markup; } bool ArgumentCoder::decode(Decoder& decoder, PasteboardWebContent& content) { if (!decoder.decode(content.text)) return false; if (!decoder.decode(content.markup)) return false; return true; } #endif // USE(LIBWPE) void ArgumentCoder::encode(Encoder& encoder, const DictationAlternative& alternative) { encoder << alternative.range << alternative.context; } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional range; decoder >> range; if (!range) return std::nullopt; std::optional context; decoder >> context; if (!context) return std::nullopt; return {{ *range, *context }}; } void ArgumentCoder::encode(Encoder& encoder, const FileChooserSettings& settings) { encoder << settings.allowsDirectories; encoder << settings.allowsMultipleFiles; encoder << settings.acceptMIMETypes; encoder << settings.acceptFileExtensions; encoder << settings.selectedFiles; #if ENABLE(MEDIA_CAPTURE) encoder << settings.mediaCaptureType; #endif } bool ArgumentCoder::decode(Decoder& decoder, FileChooserSettings& settings) { if (!decoder.decode(settings.allowsDirectories)) return false; if (!decoder.decode(settings.allowsMultipleFiles)) return false; if (!decoder.decode(settings.acceptMIMETypes)) return false; if (!decoder.decode(settings.acceptFileExtensions)) return false; if (!decoder.decode(settings.selectedFiles)) return false; #if ENABLE(MEDIA_CAPTURE) if (!decoder.decode(settings.mediaCaptureType)) return false; #endif return true; } void ArgumentCoder::encode(Encoder& encoder, const RawFile& file) { encoder << file.fileName; encodeSharedBuffer(encoder, file.fileData.get()); } bool ArgumentCoder::decode(Decoder& decoder, RawFile& file) { if (!decoder.decode(file.fileName)) return false; if (!decodeSharedBuffer(decoder, file.fileData)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const ShareData& settings) { encoder << settings.title; encoder << settings.text; encoder << settings.url; } bool ArgumentCoder::decode(Decoder& decoder, ShareData& settings) { if (!decoder.decode(settings.title)) return false; if (!decoder.decode(settings.text)) return false; if (!decoder.decode(settings.url)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const ShareDataWithParsedURL& settings) { encoder << settings.shareData; encoder << settings.url; encoder << settings.files; } bool ArgumentCoder::decode(Decoder& decoder, ShareDataWithParsedURL& settings) { if (!decoder.decode(settings.shareData)) return false; if (!decoder.decode(settings.url)) return false; if (!decoder.decode(settings.files)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const GrammarDetail& detail) { encoder << detail.range; encoder << detail.guesses; encoder << detail.userDescription; } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional range; decoder >> range; if (!range) return std::nullopt; std::optional> guesses; decoder >> guesses; if (!guesses) return std::nullopt; std::optional userDescription; decoder >> userDescription; if (!userDescription) return std::nullopt; return { { *range, WTFMove(*guesses), WTFMove(*userDescription) } }; } void ArgumentCoder::encode(Encoder& encoder, const TextCheckingRequestData& request) { encoder << request.identifier(); encoder << request.text(); encoder << request.checkingTypes(); encoder << request.processType(); } bool ArgumentCoder::decode(Decoder& decoder, TextCheckingRequestData& request) { std::optional identifier; if (!decoder.decode(identifier)) return false; String text; if (!decoder.decode(text)) return false; OptionSet checkingTypes; if (!decoder.decode(checkingTypes)) return false; TextCheckingProcessType processType; if (!decoder.decode(processType)) return false; request = TextCheckingRequestData { identifier, text, checkingTypes, processType }; return true; } void ArgumentCoder::encode(Encoder& encoder, const TextCheckingResult& result) { encoder << result.type; encoder << result.range; encoder << result.details; encoder << result.replacement; } std::optional ArgumentCoder::decode(Decoder& decoder) { TextCheckingType type; if (!decoder.decode(type)) return std::nullopt; std::optional range; decoder >> range; if (!range) return std::nullopt; std::optional> details; decoder >> details; if (!details) return std::nullopt; std::optional replacement; decoder >> replacement; if (!replacement) return std::nullopt; return { { type, *range, WTFMove(*details), WTFMove(*replacement) } }; } void ArgumentCoder::encode(Encoder& encoder, const UserStyleSheet& userStyleSheet) { encoder << userStyleSheet.source(); encoder << userStyleSheet.url(); encoder << userStyleSheet.allowlist(); encoder << userStyleSheet.blocklist(); encoder << userStyleSheet.injectedFrames(); encoder << userStyleSheet.level(); encoder << userStyleSheet.pageID(); } bool ArgumentCoder::decode(Decoder& decoder, UserStyleSheet& userStyleSheet) { String source; if (!decoder.decode(source)) return false; URL url; if (!decoder.decode(url)) return false; Vector allowlist; if (!decoder.decode(allowlist)) return false; Vector blocklist; if (!decoder.decode(blocklist)) return false; UserContentInjectedFrames injectedFrames; if (!decoder.decode(injectedFrames)) return false; UserStyleLevel level; if (!decoder.decode(level)) return false; std::optional> pageID; decoder >> pageID; if (!pageID) return false; userStyleSheet = UserStyleSheet(source, url, WTFMove(allowlist), WTFMove(blocklist), injectedFrames, level, WTFMove(*pageID)); return true; } void ArgumentCoder::encode(Encoder& encoder, const ScrollableAreaParameters& parameters) { encoder << parameters.horizontalScrollElasticity; encoder << parameters.verticalScrollElasticity; encoder << parameters.horizontalScrollbarMode; encoder << parameters.verticalScrollbarMode; encoder << parameters.allowsHorizontalScrolling; encoder << parameters.allowsVerticalScrolling; encoder << parameters.horizontalScrollbarHiddenByStyle; encoder << parameters.verticalScrollbarHiddenByStyle; encoder << parameters.useDarkAppearanceForScrollbars; } bool ArgumentCoder::decode(Decoder& decoder, ScrollableAreaParameters& params) { if (!decoder.decode(params.horizontalScrollElasticity)) return false; if (!decoder.decode(params.verticalScrollElasticity)) return false; if (!decoder.decode(params.horizontalScrollbarMode)) return false; if (!decoder.decode(params.verticalScrollbarMode)) return false; if (!decoder.decode(params.allowsHorizontalScrolling)) return false; if (!decoder.decode(params.allowsVerticalScrolling)) return false; if (!decoder.decode(params.horizontalScrollbarHiddenByStyle)) return false; if (!decoder.decode(params.verticalScrollbarHiddenByStyle)) return false; if (!decoder.decode(params.useDarkAppearanceForScrollbars)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const FixedPositionViewportConstraints& viewportConstraints) { encoder << viewportConstraints.alignmentOffset(); encoder << viewportConstraints.anchorEdges(); encoder << viewportConstraints.viewportRectAtLastLayout(); encoder << viewportConstraints.layerPositionAtLastLayout(); } bool ArgumentCoder::decode(Decoder& decoder, FixedPositionViewportConstraints& viewportConstraints) { FloatSize alignmentOffset; if (!decoder.decode(alignmentOffset)) return false; ViewportConstraints::AnchorEdges anchorEdges; if (!decoder.decode(anchorEdges)) return false; FloatRect viewportRectAtLastLayout; if (!decoder.decode(viewportRectAtLastLayout)) return false; FloatPoint layerPositionAtLastLayout; if (!decoder.decode(layerPositionAtLastLayout)) return false; viewportConstraints = FixedPositionViewportConstraints(); viewportConstraints.setAlignmentOffset(alignmentOffset); viewportConstraints.setAnchorEdges(anchorEdges); viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout); viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout); return true; } void ArgumentCoder::encode(Encoder& encoder, const AbsolutePositionConstraints& layoutConstraints) { encoder << layoutConstraints.alignmentOffset(); encoder << layoutConstraints.layerPositionAtLastLayout(); } bool ArgumentCoder::decode(Decoder& decoder, AbsolutePositionConstraints& layoutConstraints) { FloatSize alignmentOffset; if (!decoder.decode(alignmentOffset)) return false; FloatPoint layerPosition; if (!decoder.decode(layerPosition)) return false; layoutConstraints = { }; layoutConstraints.setAlignmentOffset(alignmentOffset); layoutConstraints.setLayerPositionAtLastLayout(layerPosition); return true; } void ArgumentCoder::encode(Encoder& encoder, const StickyPositionViewportConstraints& viewportConstraints) { encoder << viewportConstraints.alignmentOffset(); encoder << viewportConstraints.anchorEdges(); encoder << viewportConstraints.leftOffset(); encoder << viewportConstraints.rightOffset(); encoder << viewportConstraints.topOffset(); encoder << viewportConstraints.bottomOffset(); encoder << viewportConstraints.constrainingRectAtLastLayout(); encoder << viewportConstraints.containingBlockRect(); encoder << viewportConstraints.stickyBoxRect(); encoder << viewportConstraints.stickyOffsetAtLastLayout(); encoder << viewportConstraints.layerPositionAtLastLayout(); } bool ArgumentCoder::decode(Decoder& decoder, StickyPositionViewportConstraints& viewportConstraints) { FloatSize alignmentOffset; if (!decoder.decode(alignmentOffset)) return false; ViewportConstraints::AnchorEdges anchorEdges; if (!decoder.decode(anchorEdges)) return false; float leftOffset; if (!decoder.decode(leftOffset)) return false; float rightOffset; if (!decoder.decode(rightOffset)) return false; float topOffset; if (!decoder.decode(topOffset)) return false; float bottomOffset; if (!decoder.decode(bottomOffset)) return false; FloatRect constrainingRectAtLastLayout; if (!decoder.decode(constrainingRectAtLastLayout)) return false; FloatRect containingBlockRect; if (!decoder.decode(containingBlockRect)) return false; FloatRect stickyBoxRect; if (!decoder.decode(stickyBoxRect)) return false; FloatSize stickyOffsetAtLastLayout; if (!decoder.decode(stickyOffsetAtLastLayout)) return false; FloatPoint layerPositionAtLastLayout; if (!decoder.decode(layerPositionAtLastLayout)) return false; viewportConstraints = StickyPositionViewportConstraints(); viewportConstraints.setAlignmentOffset(alignmentOffset); viewportConstraints.setAnchorEdges(anchorEdges); viewportConstraints.setLeftOffset(leftOffset); viewportConstraints.setRightOffset(rightOffset); viewportConstraints.setTopOffset(topOffset); viewportConstraints.setBottomOffset(bottomOffset); viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout); viewportConstraints.setContainingBlockRect(containingBlockRect); viewportConstraints.setStickyBoxRect(stickyBoxRect); viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout); viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout); return true; } #if !USE(COORDINATED_GRAPHICS) void ArgumentCoder::encode(Encoder& encoder, const FilterOperation& filter) { encoder << filter.type(); switch (filter.type()) { case FilterOperation::NONE: case FilterOperation::REFERENCE: ASSERT_NOT_REACHED(); return; case FilterOperation::GRAYSCALE: case FilterOperation::SEPIA: case FilterOperation::SATURATE: case FilterOperation::HUE_ROTATE: encoder << downcast(filter).amount(); return; case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: encoder << downcast(filter).amount(); return; case FilterOperation::APPLE_INVERT_LIGHTNESS: ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter. return; case FilterOperation::BLUR: encoder << downcast(filter).stdDeviation(); return; case FilterOperation::DROP_SHADOW: { const auto& dropShadowFilter = downcast(filter); encoder << dropShadowFilter.location(); encoder << dropShadowFilter.stdDeviation(); encoder << dropShadowFilter.color(); return; } case FilterOperation::DEFAULT: encoder << downcast(filter).representedType(); return; case FilterOperation::PASSTHROUGH: return; } ASSERT_NOT_REACHED(); } bool decodeFilterOperation(Decoder& decoder, RefPtr& filter) { FilterOperation::OperationType type; if (!decoder.decode(type)) return false; switch (type) { case FilterOperation::NONE: case FilterOperation::REFERENCE: ASSERT_NOT_REACHED(); return false; case FilterOperation::GRAYSCALE: case FilterOperation::SEPIA: case FilterOperation::SATURATE: case FilterOperation::HUE_ROTATE: { double amount; if (!decoder.decode(amount)) return false; filter = BasicColorMatrixFilterOperation::create(amount, type); return true; } case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: { double amount; if (!decoder.decode(amount)) return false; filter = BasicComponentTransferFilterOperation::create(amount, type); return true; } case FilterOperation::APPLE_INVERT_LIGHTNESS: ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter. return false; case FilterOperation::BLUR: { Length stdDeviation; if (!decoder.decode(stdDeviation)) return false; filter = BlurFilterOperation::create(stdDeviation); return true; } case FilterOperation::DROP_SHADOW: { IntPoint location; int stdDeviation; Color color; if (!decoder.decode(location)) return false; if (!decoder.decode(stdDeviation)) return false; if (!decoder.decode(color)) return false; filter = DropShadowFilterOperation::create(location, stdDeviation, color); return true; } case FilterOperation::DEFAULT: { FilterOperation::OperationType representedType; if (!decoder.decode(representedType)) return false; filter = DefaultFilterOperation::create(representedType); return true; } case FilterOperation::PASSTHROUGH: filter = PassthroughFilterOperation::create(); return true; } ASSERT_NOT_REACHED(); return false; } void ArgumentCoder::encode(Encoder& encoder, const FilterOperations& filters) { encoder << static_cast(filters.size()); for (const auto& filter : filters.operations()) encoder << *filter; } bool ArgumentCoder::decode(Decoder& decoder, FilterOperations& filters) { uint64_t filterCount; if (!decoder.decode(filterCount)) return false; for (uint64_t i = 0; i < filterCount; ++i) { RefPtr filter; if (!decodeFilterOperation(decoder, filter)) return false; filters.operations().append(WTFMove(filter)); } return true; } void ArgumentCoder>::encode(Encoder& encoder, const RefPtr& operation) { encoder << !!operation; if (operation) encoder << *operation; } WARN_UNUSED_RETURN bool ArgumentCoder>::decode(Decoder& decoder, RefPtr& value) { std::optional isNull; decoder >> isNull; if (!isNull) return false; if (!decodeFilterOperation(decoder, value)) { value = nullptr; return false; } return true; } #endif // !USE(COORDINATED_GRAPHICS) void ArgumentCoder::encode(Encoder& encoder, const BlobPart& blobPart) { encoder << blobPart.type(); switch (blobPart.type()) { case BlobPart::Type::Data: encoder << blobPart.data(); return; case BlobPart::Type::Blob: encoder << blobPart.url(); return; } ASSERT_NOT_REACHED(); } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional type; decoder >> type; if (!type) return std::nullopt; switch (*type) { case BlobPart::Type::Data: { std::optional> data; decoder >> data; if (!data) return std::nullopt; return BlobPart(WTFMove(*data)); } case BlobPart::Type::Blob: { URL url; if (!decoder.decode(url)) return std::nullopt; return BlobPart(url); } } ASSERT_NOT_REACHED(); return std::nullopt; } void ArgumentCoder::encode(Encoder& encoder, const TextIndicatorData& textIndicatorData) { encoder << textIndicatorData.selectionRectInRootViewCoordinates; encoder << textIndicatorData.textBoundingRectInRootViewCoordinates; encoder << textIndicatorData.textRectsInBoundingRectCoordinates; encoder << textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates; encoder << textIndicatorData.contentImageScaleFactor; encoder << textIndicatorData.estimatedBackgroundColor; encoder << textIndicatorData.presentationTransition; encoder << textIndicatorData.options; encodeOptionalImage(encoder, textIndicatorData.contentImage.get()); encodeOptionalImage(encoder, textIndicatorData.contentImageWithHighlight.get()); encodeOptionalImage(encoder, textIndicatorData.contentImageWithoutSelection.get()); } std::optional ArgumentCoder::decode(Decoder& decoder) { TextIndicatorData textIndicatorData; if (!decoder.decode(textIndicatorData.selectionRectInRootViewCoordinates)) return std::nullopt; if (!decoder.decode(textIndicatorData.textBoundingRectInRootViewCoordinates)) return std::nullopt; if (!decoder.decode(textIndicatorData.textRectsInBoundingRectCoordinates)) return std::nullopt; if (!decoder.decode(textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates)) return std::nullopt; if (!decoder.decode(textIndicatorData.contentImageScaleFactor)) return std::nullopt; if (!decoder.decode(textIndicatorData.estimatedBackgroundColor)) return std::nullopt; if (!decoder.decode(textIndicatorData.presentationTransition)) return std::nullopt; if (!decoder.decode(textIndicatorData.options)) return std::nullopt; if (!decodeOptionalImage(decoder, textIndicatorData.contentImage)) return std::nullopt; if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithHighlight)) return std::nullopt; if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithoutSelection)) return std::nullopt; return textIndicatorData; } #if ENABLE(WIRELESS_PLAYBACK_TARGET) void ArgumentCoder::encode(Encoder& encoder, const MediaPlaybackTargetContext& target) { bool hasPlatformData = target.encodingRequiresPlatformData(); encoder << hasPlatformData; MediaPlaybackTargetContext::Type contextType = target.type(); encoder << contextType; if (target.encodingRequiresPlatformData()) { encodePlatformData(encoder, target); return; } ASSERT(contextType == MediaPlaybackTargetContext::Type::Mock); encoder << target.deviceName(); encoder << target.mockState(); } bool ArgumentCoder::decode(Decoder& decoder, MediaPlaybackTargetContext& target) { bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; MediaPlaybackTargetContext::Type contextType; if (!decoder.decode(contextType)) return false; if (hasPlatformData) return decodePlatformData(decoder, contextType, target); ASSERT(contextType == MediaPlaybackTargetContext::Type::Mock); String deviceName; if (!decoder.decode(deviceName)) return false; MediaPlaybackTargetContext::MockState mockState; if (!decoder.decode(mockState)) return false; target = MediaPlaybackTargetContext(deviceName, mockState); return true; } #endif void ArgumentCoder::encode(IPC::Encoder& encoder, const DictionaryPopupInfo& info) { encoder << info.origin; encoder << info.textIndicator; if (info.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, info); return; } encoder << false; } bool ArgumentCoder::decode(IPC::Decoder& decoder, DictionaryPopupInfo& result) { if (!decoder.decode(result.origin)) return false; std::optional textIndicator; decoder >> textIndicator; if (!textIndicator) return false; result.textIndicator = WTFMove(*textIndicator); bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, result); return true; } void ArgumentCoder::encode(IPC::Encoder& encoder, const ExceptionDetails& info) { encoder << info.message; encoder << info.lineNumber; encoder << info.columnNumber; encoder << info.type; encoder << info.sourceURL; } bool ArgumentCoder::decode(IPC::Decoder& decoder, ExceptionDetails& result) { if (!decoder.decode(result.message)) return false; if (!decoder.decode(result.lineNumber)) return false; if (!decoder.decode(result.columnNumber)) return false; if (!decoder.decode(result.type)) return false; if (!decoder.decode(result.sourceURL)) return false; return true; } void ArgumentCoder::encode(Encoder& encoder, const WebCore::ResourceLoadStatistics& statistics) { encoder << statistics.registrableDomain; encoder << statistics.lastSeen.secondsSinceEpoch().value(); // User interaction encoder << statistics.hadUserInteraction; encoder << statistics.mostRecentUserInteractionTime.secondsSinceEpoch().value(); encoder << statistics.grandfathered; // Storage access encoder << statistics.storageAccessUnderTopFrameDomains; // Top frame stats encoder << statistics.topFrameUniqueRedirectsTo; encoder << statistics.topFrameUniqueRedirectsFrom; encoder << statistics.topFrameLoadedThirdPartyScripts; // Subframe stats encoder << statistics.subframeUnderTopFrameDomains; // Subresource stats encoder << statistics.subresourceUnderTopFrameDomains; encoder << statistics.subresourceUniqueRedirectsTo; encoder << statistics.subresourceUniqueRedirectsFrom; // Prevalent Resource encoder << statistics.isPrevalentResource; encoder << statistics.isVeryPrevalentResource; encoder << statistics.dataRecordsRemoved; #if ENABLE(WEB_API_STATISTICS) encoder << statistics.fontsFailedToLoad; encoder << statistics.fontsSuccessfullyLoaded; encoder << statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs; encoder << statistics.canvasActivityRecord; encoder << statistics.navigatorFunctionsAccessed; encoder << statistics.screenFunctionsAccessed; #endif } std::optional ArgumentCoder::decode(Decoder& decoder) { ResourceLoadStatistics statistics; std::optional registrableDomain; decoder >> registrableDomain; if (!registrableDomain) return std::nullopt; statistics.registrableDomain = WTFMove(*registrableDomain); double lastSeenTimeAsDouble; if (!decoder.decode(lastSeenTimeAsDouble)) return std::nullopt; statistics.lastSeen = WallTime::fromRawSeconds(lastSeenTimeAsDouble); // User interaction if (!decoder.decode(statistics.hadUserInteraction)) return std::nullopt; double mostRecentUserInteractionTimeAsDouble; if (!decoder.decode(mostRecentUserInteractionTimeAsDouble)) return std::nullopt; statistics.mostRecentUserInteractionTime = WallTime::fromRawSeconds(mostRecentUserInteractionTimeAsDouble); if (!decoder.decode(statistics.grandfathered)) return std::nullopt; // Storage access std::optional> storageAccessUnderTopFrameDomains; decoder >> storageAccessUnderTopFrameDomains; if (!storageAccessUnderTopFrameDomains) return std::nullopt; statistics.storageAccessUnderTopFrameDomains = WTFMove(*storageAccessUnderTopFrameDomains); // Top frame stats std::optional> topFrameUniqueRedirectsTo; decoder >> topFrameUniqueRedirectsTo; if (!topFrameUniqueRedirectsTo) return std::nullopt; statistics.topFrameUniqueRedirectsTo = WTFMove(*topFrameUniqueRedirectsTo); std::optional> topFrameUniqueRedirectsFrom; decoder >> topFrameUniqueRedirectsFrom; if (!topFrameUniqueRedirectsFrom) return std::nullopt; statistics.topFrameUniqueRedirectsFrom = WTFMove(*topFrameUniqueRedirectsFrom); std::optional> topFrameLoadedThirdPartyScripts; decoder >> topFrameLoadedThirdPartyScripts; if (!topFrameLoadedThirdPartyScripts) return std::nullopt; statistics.topFrameLoadedThirdPartyScripts = WTFMove(*topFrameLoadedThirdPartyScripts); // Subframe stats std::optional> subframeUnderTopFrameDomains; decoder >> subframeUnderTopFrameDomains; if (!subframeUnderTopFrameDomains) return std::nullopt; statistics.subframeUnderTopFrameDomains = WTFMove(*subframeUnderTopFrameDomains); // Subresource stats std::optional> subresourceUnderTopFrameDomains; decoder >> subresourceUnderTopFrameDomains; if (!subresourceUnderTopFrameDomains) return std::nullopt; statistics.subresourceUnderTopFrameDomains = WTFMove(*subresourceUnderTopFrameDomains); std::optional> subresourceUniqueRedirectsTo; decoder >> subresourceUniqueRedirectsTo; if (!subresourceUniqueRedirectsTo) return std::nullopt; statistics.subresourceUniqueRedirectsTo = WTFMove(*subresourceUniqueRedirectsTo); std::optional> subresourceUniqueRedirectsFrom; decoder >> subresourceUniqueRedirectsFrom; if (!subresourceUniqueRedirectsFrom) return std::nullopt; statistics.subresourceUniqueRedirectsFrom = WTFMove(*subresourceUniqueRedirectsFrom); // Prevalent Resource if (!decoder.decode(statistics.isPrevalentResource)) return std::nullopt; if (!decoder.decode(statistics.isVeryPrevalentResource)) return std::nullopt; if (!decoder.decode(statistics.dataRecordsRemoved)) return std::nullopt; #if ENABLE(WEB_API_STATISTICS) if (!decoder.decode(statistics.fontsFailedToLoad)) return std::nullopt; if (!decoder.decode(statistics.fontsSuccessfullyLoaded)) return std::nullopt; if (!decoder.decode(statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs)) return std::nullopt; if (!decoder.decode(statistics.canvasActivityRecord)) return std::nullopt; if (!decoder.decode(statistics.navigatorFunctionsAccessed)) return std::nullopt; if (!decoder.decode(statistics.screenFunctionsAccessed)) return std::nullopt; #endif return statistics; } #if ENABLE(MEDIA_STREAM) void ArgumentCoder::encode(Encoder& encoder, const WebCore::MediaConstraints& constraint) { encoder << constraint.mandatoryConstraints << constraint.advancedConstraints << constraint.isValid; } bool ArgumentCoder::decode(Decoder& decoder, WebCore::MediaConstraints& constraints) { std::optional mandatoryConstraints; decoder >> mandatoryConstraints; if (!mandatoryConstraints) return false; constraints.mandatoryConstraints = WTFMove(*mandatoryConstraints); return decoder.decode(constraints.advancedConstraints) && decoder.decode(constraints.isValid); } #endif void ArgumentCoder::encode(Encoder& encoder, const IDBKeyPath& keyPath) { bool isString = WTF::holds_alternative(keyPath); encoder << isString; if (isString) encoder << WTF::get(keyPath); else encoder << WTF::get>(keyPath); } bool ArgumentCoder::decode(Decoder& decoder, IDBKeyPath& keyPath) { bool isString; if (!decoder.decode(isString)) return false; if (isString) { String string; if (!decoder.decode(string)) return false; keyPath = string; } else { Vector vector; if (!decoder.decode(vector)) return false; keyPath = vector; } return true; } #if ENABLE(SERVICE_WORKER) void ArgumentCoder::encode(Encoder& encoder, const ServiceWorkerOrClientData& data) { bool isServiceWorkerData = WTF::holds_alternative(data); encoder << isServiceWorkerData; if (isServiceWorkerData) encoder << WTF::get(data); else encoder << WTF::get(data); } bool ArgumentCoder::decode(Decoder& decoder, ServiceWorkerOrClientData& data) { bool isServiceWorkerData; if (!decoder.decode(isServiceWorkerData)) return false; if (isServiceWorkerData) { std::optional workerData; decoder >> workerData; if (!workerData) return false; data = WTFMove(*workerData); } else { std::optional clientData; decoder >> clientData; if (!clientData) return false; data = WTFMove(*clientData); } return true; } void ArgumentCoder::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier) { bool isServiceWorkerIdentifier = WTF::holds_alternative(identifier); encoder << isServiceWorkerIdentifier; if (isServiceWorkerIdentifier) encoder << WTF::get(identifier); else encoder << WTF::get(identifier); } bool ArgumentCoder::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier) { bool isServiceWorkerIdentifier; if (!decoder.decode(isServiceWorkerIdentifier)) return false; if (isServiceWorkerIdentifier) { std::optional workerIdentifier; decoder >> workerIdentifier; if (!workerIdentifier) return false; identifier = WTFMove(*workerIdentifier); } else { std::optional clientIdentifier; decoder >> clientIdentifier; if (!clientIdentifier) return false; identifier = WTFMove(*clientIdentifier); } return true; } #endif void ArgumentCoder::encode(Encoder& encoder, const MediaSelectionOption& option) { encoder << option.displayName; encoder << option.type; } std::optional ArgumentCoder::decode(Decoder& decoder) { std::optional displayName; decoder >> displayName; if (!displayName) return std::nullopt; std::optional type; decoder >> type; if (!type) return std::nullopt; return {{ WTFMove(*displayName), WTFMove(*type) }}; } void ArgumentCoder::encode(Encoder& encoder, const PromisedAttachmentInfo& info) { #if ENABLE(ATTACHMENT_ELEMENT) encoder << info.attachmentIdentifier; #endif encodeTypesAndData(encoder, info.additionalTypes, info.additionalData); } bool ArgumentCoder::decode(Decoder& decoder, PromisedAttachmentInfo& info) { #if ENABLE(ATTACHMENT_ELEMENT) if (!decoder.decode(info.attachmentIdentifier)) return false; #endif if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData)) return false; return true; } void ArgumentCoder>::encode(Encoder& encoder, const RefPtr& origin) { encoder << *origin; } std::optional> ArgumentCoder>::decode(Decoder& decoder) { auto origin = SecurityOrigin::decode(decoder); if (!origin) return std::nullopt; return origin; } void ArgumentCoder::encode(Encoder& encoder, const FontAttributes& attributes) { encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough << attributes.textLists; encoder << attributes.horizontalAlignment; encoder << attributes.subscriptOrSuperscript; if (attributes.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, attributes); return; } } std::optional ArgumentCoder::decode(Decoder& decoder) { FontAttributes attributes; if (!decoder.decode(attributes.backgroundColor)) return std::nullopt; if (!decoder.decode(attributes.foregroundColor)) return std::nullopt; if (!decoder.decode(attributes.fontShadow)) return std::nullopt; if (!decoder.decode(attributes.hasUnderline)) return std::nullopt; if (!decoder.decode(attributes.hasStrikeThrough)) return std::nullopt; if (!decoder.decode(attributes.textLists)) return std::nullopt; if (!decoder.decode(attributes.horizontalAlignment)) return std::nullopt; if (!decoder.decode(attributes.subscriptOrSuperscript)) return std::nullopt; bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return std::nullopt; if (hasPlatformData) return decodePlatformData(decoder, attributes); return attributes; } #if ENABLE(ATTACHMENT_ELEMENT) void ArgumentCoder::encode(IPC::Encoder& encoder, const WebCore::SerializedAttachmentData& data) { encoder << data.identifier << data.mimeType << IPC::SharedBufferDataReference { data.data.get() }; } std::optional ArgumentCoder::decode(IPC::Decoder& decoder) { String identifier; if (!decoder.decode(identifier)) return std::nullopt; String mimeType; if (!decoder.decode(mimeType)) return std::nullopt; IPC::DataReference data; if (!decoder.decode(data)) return std::nullopt; return {{ WTFMove(identifier), WTFMove(mimeType), WebCore::SharedBuffer::create(data.data(), data.size()) }}; } #endif // ENABLE(ATTACHMENT_ELEMENT) #if ENABLE(VIDEO) void ArgumentCoder::encode(Encoder& encoder, const SerializedPlatformDataCueValue& value) { bool hasPlatformData = value.encodingRequiresPlatformData(); encoder << hasPlatformData; encoder << value.platformType(); if (hasPlatformData) encodePlatformData(encoder, value); } std::optional ArgumentCoder::decode(IPC::Decoder& decoder) { bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return std::nullopt; WebCore::SerializedPlatformDataCueValue::PlatformType type; if (!decoder.decode(type)) return std::nullopt; if (hasPlatformData) return decodePlatformData(decoder, type); return { SerializedPlatformDataCueValue() }; } #endif void ArgumentCoder>::encode(Encoder& encoder, const RefPtr& buffer) { encodeSharedBuffer(encoder, buffer.get()); } std::optional> ArgumentCoder>::decode(Decoder& decoder) { RefPtr buffer; if (!decodeSharedBuffer(decoder, buffer)) return std::nullopt; return buffer; } void ArgumentCoder>::encode(Encoder& encoder, const Ref& buffer) { encodeSharedBuffer(encoder, buffer.ptr()); } std::optional> ArgumentCoder>::decode(Decoder& decoder) { RefPtr buffer; if (!decodeSharedBuffer(decoder, buffer) || !buffer) return std::nullopt; return buffer.releaseNonNull(); } #if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA) static ShareableResource::Handle tryConvertToShareableResourceHandle(const ScriptBuffer& script) { if (!script.containsSingleFileMappedSegment()) return ShareableResource::Handle { }; auto& segment = script.buffer()->begin()->segment; auto sharedMemory = SharedMemory::wrapMap(const_cast(segment->data()), segment->size(), SharedMemory::Protection::ReadOnly); if (!sharedMemory) return ShareableResource::Handle { }; auto shareableResource = ShareableResource::create(sharedMemory.releaseNonNull(), 0, segment->size()); if (!shareableResource) return ShareableResource::Handle { }; ShareableResource::Handle shareableResourceHandle; shareableResource->createHandle(shareableResourceHandle); return shareableResourceHandle; } static std::optional decodeScriptBufferAsShareableResourceHandle(Decoder& decoder) { ShareableResource::Handle handle; if (!decoder.decode(handle) || handle.isNull()) return std::nullopt; auto buffer = handle.tryWrapInSharedBuffer(); if (!buffer) return std::nullopt; return WebCore::ScriptBuffer { WTFMove(buffer) }; } #endif void ArgumentCoder::encode(Encoder& encoder, const WebCore::ScriptBuffer& script) { #if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA) auto handle = tryConvertToShareableResourceHandle(script); bool isShareableResourceHandle = !handle.isNull(); encoder << isShareableResourceHandle; if (isShareableResourceHandle) { encoder << handle; return; } #endif encodeSharedBuffer(encoder, script.buffer()); } std::optional ArgumentCoder::decode(Decoder& decoder) { #if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA) std::optional isShareableResourceHandle; decoder >> isShareableResourceHandle; if (!isShareableResourceHandle) return std::nullopt; if (*isShareableResourceHandle) return decodeScriptBufferAsShareableResourceHandle(decoder); #endif RefPtr buffer; if (!decodeSharedBuffer(decoder, buffer)) return std::nullopt; return WebCore::ScriptBuffer { WTFMove(buffer) }; } #if ENABLE(ENCRYPTED_MEDIA) void ArgumentCoder::encode(Encoder& encoder, const WebCore::CDMInstanceSession::Message& message) { encoder << message.first; RefPtr messageData = message.second.copyRef(); encoder << messageData; } std::optional ArgumentCoder::decode(Decoder& decoder) { WebCore::CDMInstanceSession::MessageType type; if (!decoder.decode(type)) return std::nullopt; RefPtr buffer; if (!decoder.decode(buffer) || !buffer) return std::nullopt; return std::make_optional({ type, buffer.releaseNonNull() }); } #endif // ENABLE(ENCRYPTED_MEDIA) #if ENABLE(GPU_PROCESS) && ENABLE(WEBGL) void ArgumentCoder::encode(Encoder& encoder, const WebCore::GraphicsContextGLAttributes& attributes) { encoder << attributes.alpha; encoder << attributes.depth; encoder << attributes.stencil; encoder << attributes.antialias; encoder << attributes.premultipliedAlpha; encoder << attributes.preserveDrawingBuffer; encoder << attributes.failIfMajorPerformanceCaveat; encoder << attributes.powerPreference; encoder << attributes.shareResources; encoder << attributes.webGLVersion; encoder << attributes.noExtensions; encoder << attributes.devicePixelRatio; encoder << attributes.initialPowerPreference; #if ENABLE(WEBXR) encoder << attributes.xrCompatible; #endif } std::optional ArgumentCoder::decode(Decoder& decoder) { GraphicsContextGLAttributes attributes; if (!decoder.decode(attributes.alpha)) return std::nullopt; if (!decoder.decode(attributes.depth)) return std::nullopt; if (!decoder.decode(attributes.stencil)) return std::nullopt; if (!decoder.decode(attributes.antialias)) return std::nullopt; if (!decoder.decode(attributes.premultipliedAlpha)) return std::nullopt; if (!decoder.decode(attributes.preserveDrawingBuffer)) return std::nullopt; if (!decoder.decode(attributes.failIfMajorPerformanceCaveat)) return std::nullopt; if (!decoder.decode(attributes.powerPreference)) return std::nullopt; if (!decoder.decode(attributes.shareResources)) return std::nullopt; if (!decoder.decode(attributes.webGLVersion)) return std::nullopt; if (!decoder.decode(attributes.noExtensions)) return std::nullopt; if (!decoder.decode(attributes.devicePixelRatio)) return std::nullopt; if (!decoder.decode(attributes.initialPowerPreference)) return std::nullopt; #if ENABLE(WEBXR) if (!decoder.decode(attributes.xrCompatible)) return std::nullopt; #endif return attributes; } template void ArgumentCoder::encode(Encoder& encoder, const WebCore::GraphicsContextGL::ActiveInfo& activeInfo) { encoder << activeInfo.name; encoder << activeInfo.type; encoder << activeInfo.size; } template void ArgumentCoder::encode(Encoder&, const WebCore::GraphicsContextGL::ActiveInfo&); template void ArgumentCoder::encode(StreamConnectionEncoder&, const WebCore::GraphicsContextGL::ActiveInfo&); std::optional ArgumentCoder::decode(Decoder& decoder) { WebCore::GraphicsContextGL::ActiveInfo activeInfo; if (!decoder.decode(activeInfo.name)) return std::nullopt; if (!decoder.decode(activeInfo.type)) return std::nullopt; if (!decoder.decode(activeInfo.size)) return std::nullopt; return activeInfo; } #endif #if ENABLE(IMAGE_ANALYSIS) && ENABLE(DATA_DETECTION) void ArgumentCoder::encode(Encoder& encoder, const TextRecognitionDataDetector& info) { encodePlatformData(encoder, info); encoder << info.normalizedQuads; } std::optional ArgumentCoder::decode(Decoder& decoder) { TextRecognitionDataDetector result; if (!decodePlatformData(decoder, result)) return std::nullopt; std::optional> normalizedQuads; decoder >> normalizedQuads; if (!normalizedQuads) return std::nullopt; result.normalizedQuads = WTFMove(*normalizedQuads); return WTFMove(result); } #endif // ENABLE(IMAGE_ANALYSIS) && ENABLE(DATA_DETECTION) } // namespace IPC