Title: [295545] trunk/Source/WebKit
Revision
295545
Author
[email protected]
Date
2022-06-14 16:54:35 -0700 (Tue, 14 Jun 2022)

Log Message

Return error when parsing badly encoded std::variant IPC messages.
https://bugs.webkit.org/show_bug.cgi?id=241547
rdar://problem/95016858

Reviewed by Kimmo Kinnunen.

We check the variant's index at the start and insure its validity,
returning early of an invalid type index is found rather than asserting.

Code covered by making PasteboardCustomData::Entry use the std::variant encoder
and covered with ipc/pasteboard-write-custom-data.html

* Source/WebKit/Platform/IPC/ArgumentCoders.h:
* Source/WebKit/Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<PasteboardCustomData::Entry>::encode):
(IPC::ArgumentCoder<PasteboardCustomData::Entry>::decode):

Canonical link: https://commits.webkit.org/251550@main

Modified Paths

Diff

Modified: trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h (295544 => 295545)


--- trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h	2022-06-14 22:59:43 UTC (rev 295544)
+++ trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h	2022-06-14 23:54:35 UTC (rev 295545)
@@ -206,7 +206,7 @@
 };
 
 template<typename T> struct ArgumentCoder<std::optional<T>> {
-    
+
     template<typename Encoder> static void encode(Encoder& encoder, const std::optional<T>& optional)
     {
         if (!optional) {
@@ -236,7 +236,7 @@
         optional = WTFMove(value);
         return true;
     }
-    
+
     template<typename Decoder> static std::optional<std::optional<T>> decode(Decoder& decoder)
     {
         std::optional<bool> isEngaged;
@@ -335,12 +335,12 @@
         decoder >> first;
         if (!first)
             return std::nullopt;
-        
+
         std::optional<U> second;
         decoder >> second;
         if (!second)
             return std::nullopt;
-        
+
         return {{ WTFMove(*first), WTFMove(*second) }};
     }
 };
@@ -521,7 +521,7 @@
         encoder << static_cast<uint64_t>(vector.size());
         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(vector.data()), vector.size() * sizeof(T), alignof(T));
     }
-    
+
     template<typename Decoder>
     static WARN_UNUSED_RETURN bool decode(Decoder& decoder, Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
     {
@@ -549,7 +549,7 @@
         vector.swap(temp);
         return true;
     }
-    
+
     template<typename Decoder>
     static std::optional<Vector<T, inlineCapacity, OverflowHandler, minCapacity>> decode(Decoder& decoder)
     {
@@ -568,7 +568,7 @@
         // is big enough.
         if (!decoder.template bufferIsLargeEnoughToContain<T>(size))
             return std::nullopt;
-        
+
         Vector<T, inlineCapacity, OverflowHandler, minCapacity> vector;
         vector.grow(size);
 
@@ -687,18 +687,18 @@
 
 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashCountedSet<KeyArg, HashArg, KeyTraitsArg>> {
     typedef HashCountedSet<KeyArg, HashArg, KeyTraitsArg> HashCountedSetType;
-    
+
     template<typename Encoder>
     static void encode(Encoder& encoder, const HashCountedSetType& hashCountedSet)
     {
         encoder << static_cast<uint64_t>(hashCountedSet.size());
-        
+
         for (auto entry : hashCountedSet) {
             encoder << entry.key;
             encoder << entry.value;
         }
     }
-    
+
     template<typename Decoder>
     static WARN_UNUSED_RETURN bool decode(Decoder& decoder, HashCountedSetType& hashCountedSet)
     {
@@ -705,13 +705,13 @@
         uint64_t hashCountedSetSize;
         if (!decoder.decode(hashCountedSetSize))
             return false;
-        
+
         HashCountedSetType tempHashCountedSet;
         for (uint64_t i = 0; i < hashCountedSetSize; ++i) {
             KeyArg key;
             if (!decoder.decode(key))
                 return false;
-            
+
             unsigned count;
             if (!decoder.decode(count))
                 return false;
@@ -724,7 +724,7 @@
                 return false;
             }
         }
-        
+
         hashCountedSet.swap(tempHashCountedSet);
         return true;
     }
@@ -750,13 +750,13 @@
         decoder >> hasValue;
         if (!hasValue)
             return std::nullopt;
-        
+
         if (*hasValue) {
             std::optional<ValueType> value;
             decoder >> value;
             if (!value)
                 return std::nullopt;
-            
+
             Expected<ValueType, ErrorType> expected(WTFMove(*value));
             return expected;
         }
@@ -779,7 +779,7 @@
 
         encoder << true;
     }
-    
+
     template<typename Decoder> static std::optional<Expected<void, ErrorType>> decode(Decoder& decoder)
     {
         std::optional<bool> hasValue;
@@ -809,7 +809,7 @@
         }
         VariantCoder<index - 1, Types...>::encode(encoder, variant, i);
     }
-    
+
     template<typename Decoder>
     static std::optional<std::variant<Types...>> decode(Decoder& decoder, unsigned i)
     {
@@ -832,7 +832,7 @@
         ASSERT_UNUSED(i, !i);
         encoder << std::get<0>(variant);
     }
-    
+
     template<typename Decoder>
     static std::optional<std::variant<Types...>> decode(Decoder& decoder, unsigned i)
     {
@@ -853,18 +853,18 @@
         encoder << i;
         VariantCoder<sizeof...(Types) - 1, Types...>::encode(encoder, variant, i);
     }
-    
+
     template<typename Decoder>
     static std::optional<std::variant<Types...>> decode(Decoder& decoder)
     {
         std::optional<unsigned> i;
         decoder >> i;
-        if (!i)
+        if (!i || *i >= sizeof...(Types))
             return std::nullopt;
         return VariantCoder<sizeof...(Types) - 1, Types...>::decode(decoder, *i);
     }
 };
-    
+
 template<> struct ArgumentCoder<WallTime> {
     template<typename Encoder>
     static void encode(Encoder&, const WallTime&);

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (295544 => 295545)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2022-06-14 22:59:43 UTC (rev 295544)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2022-06-14 23:54:35 UTC (rev 295545)
@@ -1466,54 +1466,12 @@
 
 void ArgumentCoder<PasteboardCustomData::Entry>::encode(Encoder& encoder, const PasteboardCustomData::Entry& data)
 {
-    encoder << data.type << data.customData;
-
-    auto& platformData = data.platformData;
-    bool hasString = std::holds_alternative<String>(platformData);
-    encoder << hasString;
-    if (hasString)
-        encoder << std::get<String>(platformData);
-
-    bool hasBuffer = std::holds_alternative<Ref<SharedBuffer>>(platformData);
-    encoder << hasBuffer;
-    if (hasBuffer)
-        encoder << std::get<Ref<SharedBuffer>>(platformData);
+    encoder << data.type << data.customData << data.platformData;
 }
 
 bool ArgumentCoder<PasteboardCustomData::Entry>::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) {
-        auto buffer = decoder.decode<Ref<SharedBuffer>>();
-        if (!buffer)
-            return false;
-        data.platformData = { WTFMove(*buffer) };
-    }
-
-    return true;
+    return decoder.decode(data.type) && decoder.decode(data.customData) && decoder.decode(data.platformData);
 }
 
 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to