Title: [291673] branches/safari-613-branch
Revision
291673
Author
alanc...@apple.com
Date
2022-03-22 10:57:16 -0700 (Tue, 22 Mar 2022)

Log Message

Cherry-pick r291518. rdar://problem/90124325

    [Cocoa] Teach WebKit how to serialize CGColors
    https://bugs.webkit.org/show_bug.cgi?id=238069
    <rdar://problem/90124325>

    Reviewed by Dean Jackson and Tim Horton.

    Source/WebKit:

    We have 2 ways of serializing Cocoa objects: NS type handling in ArgumentCodersCocoa.mm,
    and CF type handling in ArgumentCodersCF.mm. CGColors are CF types, so this patch adds
    direct support in ArgumentCodersCF to serialize them, by round-tripping them through
    WebCore::Colors. However, NS containers (like font descriptor attribute dictionaries)
    can contain CGColors, so this patch also teaches ArgumentCodersCocoa that there may be
    CF types inside NS containers. If one is present, ArgumentCodersCocoa has to call into
    ArgumentCodersCF to serialize it.

    This patch doesn't add support for the reverse path, where an NS object is contained
    within a CF container. I intentionally omitted implementing this because I wasn't sure
    if it would be a layering violation; ArgumentCodersCococa.mm already #includes
    ArgumentCodersCF.h, but ArgumentCodersCF.mm doesn't #include ArgumentCodersCocoa.h.
    This path isn't actually necessary to solve my problem at hand, so someone else can
    add support if necessary in the future. I also added a comment at the site where the
    code would fail, describing what the problem is and a potential workaround.

    This patch also adds support for our NSSecureCoding implementation for CGColors. This
    is necessary because sometimes we want to serialize things like NSAttributedStrings,
    which we don't have direct support for, so we use NSSecureCoding to serialize them
    instead. NSAttributedStrings can contain fonts whose descriptor dictionaries contain
    CGColors, so this path needs to work with CGColors too. Support is implemented using
    NSKeyedArchiverDelegate and NSKeyedUnarchiverDelegate.

    Test: IPCTestingAPI.CGColorInNSSecureCoding
          The non-NSSecureCoding parts of this patch are tested by our regular LayoutTests
          when DOM GPU Process rendering is enabled.

    * Shared/Cocoa/ArgumentCodersCocoa.mm:
    (-[WKSecureCodingArchivingDelegate archiver:willEncodeObject:]):
    (-[WKSecureCodingArchivingDelegate unarchiver:didDecodeObject:]):
    (-[WKSecureCodingCGColorWrapper wrappedColor]):
    (+[WKSecureCodingCGColorWrapper supportsSecureCoding]):
    (-[WKSecureCodingCGColorWrapper encodeWithCoder:]):
    (-[WKSecureCodingCGColorWrapper initWithCoder:]):
    (-[WKSecureCodingCGColorWrapper initWithCGColor:]):
    (IPC::typeFromObject):
    (IPC::decodeSecureCodingInternal):
    (IPC::encodeCFInternal):
    (IPC::decodeCFInternal):
    (IPC::encodeObject):
    (IPC::decodeObject):
    * Shared/cf/ArgumentCodersCF.cpp:
    (IPC::typeFromCFTypeRef):
    (IPC::ArgumentCoder<CFTypeRef>::encode):
    (IPC::ArgumentCoder<RetainPtr<CFTypeRef>>::decode):
    (IPC::ArgumentCoder<CGColorRef>::encode):
    (IPC::ArgumentCoder<RetainPtr<CGColorRef>>::decode):
    * Shared/cf/ArgumentCodersCF.h:

    Tools:

    * Scripts/webkitpy/style/checkers/cpp.py:
    * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291518 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-613-branch/Source/WebKit/ChangeLog (291672 => 291673)


--- branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-22 17:57:16 UTC (rev 291673)
@@ -1,5 +1,130 @@
 2022-03-21  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r291518. rdar://problem/90124325
+
+    [Cocoa] Teach WebKit how to serialize CGColors
+    https://bugs.webkit.org/show_bug.cgi?id=238069
+    <rdar://problem/90124325>
+    
+    Reviewed by Dean Jackson and Tim Horton.
+    
+    Source/WebKit:
+    
+    We have 2 ways of serializing Cocoa objects: NS type handling in ArgumentCodersCocoa.mm,
+    and CF type handling in ArgumentCodersCF.mm. CGColors are CF types, so this patch adds
+    direct support in ArgumentCodersCF to serialize them, by round-tripping them through
+    WebCore::Colors. However, NS containers (like font descriptor attribute dictionaries)
+    can contain CGColors, so this patch also teaches ArgumentCodersCocoa that there may be
+    CF types inside NS containers. If one is present, ArgumentCodersCocoa has to call into
+    ArgumentCodersCF to serialize it.
+    
+    This patch doesn't add support for the reverse path, where an NS object is contained
+    within a CF container. I intentionally omitted implementing this because I wasn't sure
+    if it would be a layering violation; ArgumentCodersCococa.mm already #includes
+    ArgumentCodersCF.h, but ArgumentCodersCF.mm doesn't #include ArgumentCodersCocoa.h.
+    This path isn't actually necessary to solve my problem at hand, so someone else can
+    add support if necessary in the future. I also added a comment at the site where the
+    code would fail, describing what the problem is and a potential workaround.
+    
+    This patch also adds support for our NSSecureCoding implementation for CGColors. This
+    is necessary because sometimes we want to serialize things like NSAttributedStrings,
+    which we don't have direct support for, so we use NSSecureCoding to serialize them
+    instead. NSAttributedStrings can contain fonts whose descriptor dictionaries contain
+    CGColors, so this path needs to work with CGColors too. Support is implemented using
+    NSKeyedArchiverDelegate and NSKeyedUnarchiverDelegate.
+    
+    Test: IPCTestingAPI.CGColorInNSSecureCoding
+          The non-NSSecureCoding parts of this patch are tested by our regular LayoutTests
+          when DOM GPU Process rendering is enabled.
+    
+    * Shared/Cocoa/ArgumentCodersCocoa.mm:
+    (-[WKSecureCodingArchivingDelegate archiver:willEncodeObject:]):
+    (-[WKSecureCodingArchivingDelegate unarchiver:didDecodeObject:]):
+    (-[WKSecureCodingCGColorWrapper wrappedColor]):
+    (+[WKSecureCodingCGColorWrapper supportsSecureCoding]):
+    (-[WKSecureCodingCGColorWrapper encodeWithCoder:]):
+    (-[WKSecureCodingCGColorWrapper initWithCoder:]):
+    (-[WKSecureCodingCGColorWrapper initWithCGColor:]):
+    (IPC::typeFromObject):
+    (IPC::decodeSecureCodingInternal):
+    (IPC::encodeCFInternal):
+    (IPC::decodeCFInternal):
+    (IPC::encodeObject):
+    (IPC::decodeObject):
+    * Shared/cf/ArgumentCodersCF.cpp:
+    (IPC::typeFromCFTypeRef):
+    (IPC::ArgumentCoder<CFTypeRef>::encode):
+    (IPC::ArgumentCoder<RetainPtr<CFTypeRef>>::decode):
+    (IPC::ArgumentCoder<CGColorRef>::encode):
+    (IPC::ArgumentCoder<RetainPtr<CGColorRef>>::decode):
+    * Shared/cf/ArgumentCodersCF.h:
+    
+    Tools:
+    
+    * Scripts/webkitpy/style/checkers/cpp.py:
+    * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-18  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+            [Cocoa] Teach WebKit how to serialize CGColors
+            https://bugs.webkit.org/show_bug.cgi?id=238069
+            <rdar://problem/90124325>
+
+            Reviewed by Dean Jackson and Tim Horton.
+
+            We have 2 ways of serializing Cocoa objects: NS type handling in ArgumentCodersCocoa.mm,
+            and CF type handling in ArgumentCodersCF.mm. CGColors are CF types, so this patch adds
+            direct support in ArgumentCodersCF to serialize them, by round-tripping them through
+            WebCore::Colors. However, NS containers (like font descriptor attribute dictionaries)
+            can contain CGColors, so this patch also teaches ArgumentCodersCocoa that there may be
+            CF types inside NS containers. If one is present, ArgumentCodersCocoa has to call into
+            ArgumentCodersCF to serialize it.
+
+            This patch doesn't add support for the reverse path, where an NS object is contained
+            within a CF container. I intentionally omitted implementing this because I wasn't sure
+            if it would be a layering violation; ArgumentCodersCococa.mm already #includes
+            ArgumentCodersCF.h, but ArgumentCodersCF.mm doesn't #include ArgumentCodersCocoa.h.
+            This path isn't actually necessary to solve my problem at hand, so someone else can
+            add support if necessary in the future. I also added a comment at the site where the
+            code would fail, describing what the problem is and a potential workaround.
+
+            This patch also adds support for our NSSecureCoding implementation for CGColors. This
+            is necessary because sometimes we want to serialize things like NSAttributedStrings,
+            which we don't have direct support for, so we use NSSecureCoding to serialize them
+            instead. NSAttributedStrings can contain fonts whose descriptor dictionaries contain
+            CGColors, so this path needs to work with CGColors too. Support is implemented using
+            NSKeyedArchiverDelegate and NSKeyedUnarchiverDelegate.
+
+            Test: IPCTestingAPI.CGColorInNSSecureCoding
+                  The non-NSSecureCoding parts of this patch are tested by our regular LayoutTests
+                  when DOM GPU Process rendering is enabled.
+
+            * Shared/Cocoa/ArgumentCodersCocoa.mm:
+            (-[WKSecureCodingArchivingDelegate archiver:willEncodeObject:]):
+            (-[WKSecureCodingArchivingDelegate unarchiver:didDecodeObject:]):
+            (-[WKSecureCodingCGColorWrapper wrappedColor]):
+            (+[WKSecureCodingCGColorWrapper supportsSecureCoding]):
+            (-[WKSecureCodingCGColorWrapper encodeWithCoder:]):
+            (-[WKSecureCodingCGColorWrapper initWithCoder:]):
+            (-[WKSecureCodingCGColorWrapper initWithCGColor:]):
+            (IPC::typeFromObject):
+            (IPC::decodeSecureCodingInternal):
+            (IPC::encodeCFInternal):
+            (IPC::decodeCFInternal):
+            (IPC::encodeObject):
+            (IPC::decodeObject):
+            * Shared/cf/ArgumentCodersCF.cpp:
+            (IPC::typeFromCFTypeRef):
+            (IPC::ArgumentCoder<CFTypeRef>::encode):
+            (IPC::ArgumentCoder<RetainPtr<CFTypeRef>>::decode):
+            (IPC::ArgumentCoder<CGColorRef>::encode):
+            (IPC::ArgumentCoder<RetainPtr<CGColorRef>>::decode):
+            * Shared/cf/ArgumentCodersCF.h:
+
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r291326. rdar://problem/85551863
 
     Video poster disappears prematurely on play, leaving transparent video element.

Modified: branches/safari-613-branch/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm (291672 => 291673)


--- branches/safari-613-branch/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm	2022-03-22 17:57:16 UTC (rev 291673)
@@ -52,26 +52,40 @@
 @end
 
 @interface WKSecureCodingURLWrapper : NSURL <NSSecureCoding>
-- (instancetype _Nullable)initWithURL:(NSURL *)wrappedURL;
+- (instancetype)initWithURL:(NSURL *)wrappedURL;
 @property (nonatomic, readonly) NSURL * wrappedURL;
 @end
 
+@interface WKSecureCodingCGColorWrapper : NSObject <NSSecureCoding>
+- (instancetype)initWithCGColor:(CGColorRef)wrappedColor;
+@property (nonatomic, readonly) CGColorRef wrappedColor;
+@end
+
 @implementation WKSecureCodingArchivingDelegate
 
-- (nullable id)archiver:(NSKeyedArchiver *)archiver willEncodeObject:(id)object
+- (id)archiver:(NSKeyedArchiver *)archiver willEncodeObject:(id)object
 {
     if (auto unwrappedURL = dynamic_objc_cast<NSURL>(object))
         return adoptNS([[WKSecureCodingURLWrapper alloc] initWithURL:unwrappedURL]).autorelease();
 
+    // We can't just return a WebCore::CocoaColor here, because the decoder would
+    // have no way of distinguishing an authentic WebCore::CocoaColor vs a CGColor
+    // masquerading as a WebCore::CocoaColor.
+    if (CFGetTypeID(object) == CGColorGetTypeID())
+        return adoptNS([[WKSecureCodingCGColorWrapper alloc] initWithCGColor:static_cast<CGColorRef>(object)]).autorelease();
+
     return object;
 }
 
-- (id _Nullable)unarchiver:(NSKeyedUnarchiver *)unarchiver didDecodeObject:(id _Nullable) NS_RELEASES_ARGUMENT object NS_RETURNS_RETAINED
+- (id)unarchiver:(NSKeyedUnarchiver *)unarchiver didDecodeObject:(id) NS_RELEASES_ARGUMENT object NS_RETURNS_RETAINED
 {
     auto adoptedObject = adoptNS(object);
     if (auto wrapper = dynamic_objc_cast<WKSecureCodingURLWrapper>(adoptedObject.get()))
         return retainPtr(wrapper.wrappedURL).leakRef();
 
+    if (auto wrapper = dynamic_objc_cast<WKSecureCodingCGColorWrapper>(adoptedObject.get()))
+        return static_cast<id>(retainPtr(wrapper.wrappedColor).leakRef());
+
     return adoptedObject.leakRef();
 }
 
@@ -107,7 +121,7 @@
     [coder encodeBytes:bytes.data() length:bytes.size()];
 }
 
-- (_Nullable instancetype)initWithCoder:(NSCoder *)coder
+- (instancetype)initWithCoder:(NSCoder *)coder
 {
     auto selfPtr = adoptNS([super initWithString:@""]);
     if (!selfPtr)
@@ -133,7 +147,7 @@
     return selfPtr.leakRef();
 }
 
-- (_Nullable instancetype)initWithURL:(NSURL *)url
+- (instancetype)initWithURL:(NSURL *)url
 {
     if (self = [super initWithString:@""])
         m_wrappedURL = url;
@@ -143,6 +157,50 @@
 
 @end
 
+@implementation WKSecureCodingCGColorWrapper {
+    RetainPtr<CGColorRef> m_wrappedColor;
+}
+
+- (CGColorRef)wrappedColor
+{
+    return m_wrappedColor.get();
+}
+
++ (BOOL)supportsSecureCoding
+{
+    return YES;
+}
+
+static constexpr NSString *innerColorKey = @"WK.CocoaColor";
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+    RELEASE_ASSERT(m_wrappedColor);
+    [coder encodeObject:[WebCore::CocoaColor colorWithCGColor:m_wrappedColor.get()] forKey:innerColorKey];
+}
+
+- (instancetype)initWithCoder:(NSCoder *)coder
+{
+    auto selfPtr = adoptNS([super init]);
+    if (!selfPtr)
+        return nil;
+
+    RetainPtr<WebCore::CocoaColor> color = static_cast<WebCore::CocoaColor *>([coder decodeObjectOfClass:[WebCore::CocoaColor class] forKey:innerColorKey]);
+    m_wrappedColor = color.get().CGColor;
+
+    return selfPtr.leakRef();
+}
+
+- (instancetype)initWithCGColor:(CGColorRef)color
+{
+    if (self = [super init])
+        m_wrappedColor = color;
+
+    return self;
+}
+
+@end
+
 namespace IPC {
 using namespace WebCore;
 
@@ -159,6 +217,7 @@
     SecureCoding,
     String,
     URL,
+    CF,
     Unknown,
 };
 
@@ -187,6 +246,10 @@
         return NSType::String;
     if ([object isKindOfClass:[NSURL class]])
         return NSType::URL;
+    // Not all CF types are toll-free-bridged to NS types.
+    // Non-toll-free-bridged CF types do not conform to NSSecureCoding.
+    if ([object isKindOfClass:NSClassFromString(@"__NSCFType")])
+        return NSType::CF;
 
     // Check NSSecureCoding after the specific cases since
     // most of the classes above conform to NSSecureCoding,
@@ -430,6 +493,7 @@
 
     auto allowedClassSet = adoptNS([[NSMutableSet alloc] initWithArray:allowedClasses]);
     [allowedClassSet addObject:WKSecureCodingURLWrapper.class];
+    [allowedClassSet addObject:WKSecureCodingCGColorWrapper.class];
     
     @try {
         id result = [unarchiver decodeObjectOfClasses:allowedClassSet.get() forKey:NSKeyedArchiveRootObjectKey];
@@ -474,6 +538,22 @@
     return { bridge_cast(WTFMove(URL)) };
 }
 
+#pragma mark - CF
+
+static inline void encodeCFInternal(Encoder& encoder, CFTypeRef cf)
+{
+    ArgumentCoder<CFTypeRef>::encode(encoder, cf);
+}
+
+static inline std::optional<RetainPtr<id>> decodeCFInternal(Decoder& decoder)
+{
+    auto result = ArgumentCoder<RetainPtr<CFTypeRef>>::decode(decoder);
+    if (!result)
+        return std::nullopt;
+
+    return static_cast<id>(result->get());
+}
+
 #pragma mark - Entry Point Encoder / Decoder
 
 void encodeObject(Encoder& encoder, id object)
@@ -516,6 +596,9 @@
     case NSType::URL:
         encodeURLInternal(encoder, static_cast<NSURL *>(object));
         return;
+    case NSType::CF:
+        encodeCFInternal(encoder, static_cast<CFTypeRef>(object));
+        return;
     case NSType::Unknown:
         break;
     }
@@ -556,6 +639,8 @@
         return decodeDataInternal(decoder);
     case NSType::URL:
         return decodeURLInternal(decoder);
+    case NSType::CF:
+        return decodeCFInternal(decoder);
     case NSType::Unknown:
         break;
     }
@@ -580,6 +665,7 @@
         IPC::NSType::SecureCoding,
         IPC::NSType::String,
         IPC::NSType::URL,
+        IPC::NSType::CF,
         IPC::NSType::Unknown
     >;
 };

Modified: branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.cpp (291672 => 291673)


--- branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.cpp	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.cpp	2022-03-22 17:57:16 UTC (rev 291673)
@@ -36,6 +36,7 @@
 #include "Encoder.h"
 #include "StreamConnectionEncoder.h"
 #include <CoreGraphics/CoreGraphics.h>
+#include <WebCore/Color.h>
 #include <wtf/EnumTraits.h>
 #include <wtf/HashSet.h>
 #include <wtf/ProcessPrivilege.h>
@@ -77,6 +78,7 @@
     SecTrust,
 #endif
     CGColorSpace,
+    CGColor,
     Nullptr,
     Unknown,
 };
@@ -109,6 +111,8 @@
         return CFType::CFURL;
     if (typeID == CGColorSpaceGetTypeID())
         return CFType::CGColorSpace;
+    if (typeID == CGColorGetTypeID())
+        return CFType::CGColor;
     if (typeID == SecCertificateGetTypeID())
         return CFType::SecCertificate;
 #if HAVE(SEC_KEYCHAIN)
@@ -124,6 +128,8 @@
         return CFType::SecTrust;
 #endif
 
+    // If you're hitting this, it probably means that you've put an NS type inside a CF container.
+    // Try round-tripping the container through an NS type instead.
     ASSERT_NOT_REACHED();
     return CFType::Unknown;
 }
@@ -165,6 +171,9 @@
     case CFType::CGColorSpace:
         encoder << static_cast<CGColorSpaceRef>(const_cast<void*>(typeRef));
         return;
+    case CFType::CGColor:
+        encoder << static_cast<CGColorRef>(const_cast<void*>(typeRef));
+        return;
     case CFType::SecCertificate:
         encoder << static_cast<SecCertificateRef>(const_cast<void*>(typeRef));
         return;
@@ -268,6 +277,13 @@
             return std::nullopt;
         return WTFMove(*colorSpace);
     }
+    case CFType::CGColor: {
+        std::optional<RetainPtr<CGColorRef>> color;
+        decoder >> color;
+        if (!color)
+            return std::nullopt;
+        return WTFMove(*color);
+    }
     case CFType::SecCertificate: {
         std::optional<RetainPtr<SecCertificateRef>> certificate;
         decoder >> certificate;
@@ -739,7 +755,24 @@
     return std::nullopt;
 }
 
+template<typename Encoder>
+void ArgumentCoder<CGColorRef>::encode(Encoder& encoder, CGColorRef color)
+{
+    encoder << WebCore::Color::createAndPreserveColorSpace(color);
+}
 
+template void ArgumentCoder<CGColorRef>::encode<Encoder>(Encoder&, CGColorRef);
+template void ArgumentCoder<CGColorRef>::encode<StreamConnectionEncoder>(StreamConnectionEncoder&, CGColorRef);
+
+std::optional<RetainPtr<CGColorRef>> ArgumentCoder<RetainPtr<CGColorRef>>::decode(Decoder& decoder)
+{
+    std::optional<WebCore::Color> color;
+    decoder >> color;
+    if (!color)
+        return std::nullopt;
+    return cachedCGColor(*color);
+}
+
 template<typename Encoder>
 void ArgumentCoder<SecCertificateRef>::encode(Encoder& encoder, SecCertificateRef certificate)
 {
@@ -895,6 +928,7 @@
         IPC::CFType::SecTrust,
 #endif
         IPC::CFType::CGColorSpace,
+        IPC::CFType::CGColor,
         IPC::CFType::Nullptr,
         IPC::CFType::Unknown
     >;

Modified: branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.h (291672 => 291673)


--- branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.h	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Source/WebKit/Shared/cf/ArgumentCodersCF.h	2022-03-22 17:57:16 UTC (rev 291673)
@@ -41,9 +41,6 @@
 class Encoder;
 class Decoder;
 
-// NOTE: These coders are structured such that they expose encoder functions for both CFType and RetainPtr<CFType>
-// but only a decoder only for RetainPtr<CFType>.
-
 template<typename T>
 struct CFRetainPtrArgumentCoder {
     template<typename Encoder> static void encode(Encoder& encoder, const RetainPtr<T>& retainPtr)
@@ -122,6 +119,13 @@
     static std::optional<RetainPtr<CGColorSpaceRef>> decode(Decoder&);
 };
 
+template<> struct ArgumentCoder<CGColorRef> {
+    template<typename Encoder> static void encode(Encoder&, CGColorRef);
+};
+template<> struct ArgumentCoder<RetainPtr<CGColorRef>> : CFRetainPtrArgumentCoder<CGColorRef> {
+    static std::optional<RetainPtr<CGColorRef>> decode(Decoder&);
+};
+
 template<> struct ArgumentCoder<SecCertificateRef> {
     template<typename Encoder> static void encode(Encoder&, SecCertificateRef);
 };

Modified: branches/safari-613-branch/Tools/ChangeLog (291672 => 291673)


--- branches/safari-613-branch/Tools/ChangeLog	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Tools/ChangeLog	2022-03-22 17:57:16 UTC (rev 291673)
@@ -1,5 +1,84 @@
 2022-03-21  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r291518. rdar://problem/90124325
+
+    [Cocoa] Teach WebKit how to serialize CGColors
+    https://bugs.webkit.org/show_bug.cgi?id=238069
+    <rdar://problem/90124325>
+    
+    Reviewed by Dean Jackson and Tim Horton.
+    
+    Source/WebKit:
+    
+    We have 2 ways of serializing Cocoa objects: NS type handling in ArgumentCodersCocoa.mm,
+    and CF type handling in ArgumentCodersCF.mm. CGColors are CF types, so this patch adds
+    direct support in ArgumentCodersCF to serialize them, by round-tripping them through
+    WebCore::Colors. However, NS containers (like font descriptor attribute dictionaries)
+    can contain CGColors, so this patch also teaches ArgumentCodersCocoa that there may be
+    CF types inside NS containers. If one is present, ArgumentCodersCocoa has to call into
+    ArgumentCodersCF to serialize it.
+    
+    This patch doesn't add support for the reverse path, where an NS object is contained
+    within a CF container. I intentionally omitted implementing this because I wasn't sure
+    if it would be a layering violation; ArgumentCodersCococa.mm already #includes
+    ArgumentCodersCF.h, but ArgumentCodersCF.mm doesn't #include ArgumentCodersCocoa.h.
+    This path isn't actually necessary to solve my problem at hand, so someone else can
+    add support if necessary in the future. I also added a comment at the site where the
+    code would fail, describing what the problem is and a potential workaround.
+    
+    This patch also adds support for our NSSecureCoding implementation for CGColors. This
+    is necessary because sometimes we want to serialize things like NSAttributedStrings,
+    which we don't have direct support for, so we use NSSecureCoding to serialize them
+    instead. NSAttributedStrings can contain fonts whose descriptor dictionaries contain
+    CGColors, so this path needs to work with CGColors too. Support is implemented using
+    NSKeyedArchiverDelegate and NSKeyedUnarchiverDelegate.
+    
+    Test: IPCTestingAPI.CGColorInNSSecureCoding
+          The non-NSSecureCoding parts of this patch are tested by our regular LayoutTests
+          when DOM GPU Process rendering is enabled.
+    
+    * Shared/Cocoa/ArgumentCodersCocoa.mm:
+    (-[WKSecureCodingArchivingDelegate archiver:willEncodeObject:]):
+    (-[WKSecureCodingArchivingDelegate unarchiver:didDecodeObject:]):
+    (-[WKSecureCodingCGColorWrapper wrappedColor]):
+    (+[WKSecureCodingCGColorWrapper supportsSecureCoding]):
+    (-[WKSecureCodingCGColorWrapper encodeWithCoder:]):
+    (-[WKSecureCodingCGColorWrapper initWithCoder:]):
+    (-[WKSecureCodingCGColorWrapper initWithCGColor:]):
+    (IPC::typeFromObject):
+    (IPC::decodeSecureCodingInternal):
+    (IPC::encodeCFInternal):
+    (IPC::decodeCFInternal):
+    (IPC::encodeObject):
+    (IPC::decodeObject):
+    * Shared/cf/ArgumentCodersCF.cpp:
+    (IPC::typeFromCFTypeRef):
+    (IPC::ArgumentCoder<CFTypeRef>::encode):
+    (IPC::ArgumentCoder<RetainPtr<CFTypeRef>>::decode):
+    (IPC::ArgumentCoder<CGColorRef>::encode):
+    (IPC::ArgumentCoder<RetainPtr<CGColorRef>>::decode):
+    * Shared/cf/ArgumentCodersCF.h:
+    
+    Tools:
+    
+    * Scripts/webkitpy/style/checkers/cpp.py:
+    * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291518 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-18  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+            [Cocoa] Teach WebKit how to serialize CGColors
+            https://bugs.webkit.org/show_bug.cgi?id=238069
+            <rdar://problem/90124325>
+
+            Reviewed by Dean Jackson and Tim Horton.
+
+            * Scripts/webkitpy/style/checkers/cpp.py:
+            * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
+
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r290539. rdar://problem/88767812
 
     [WebAuthn] Fallback to attestation=none whenever attestation fails

Modified: branches/safari-613-branch/Tools/Scripts/webkitpy/style/checkers/cpp.py (291672 => 291673)


--- branches/safari-613-branch/Tools/Scripts/webkitpy/style/checkers/cpp.py	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Tools/Scripts/webkitpy/style/checkers/cpp.py	2022-03-22 17:57:16 UTC (rev 291673)
@@ -2546,7 +2546,7 @@
 
 
 # Enum declaration allowlist
-_ALLOW_ALL_UPPERCASE_ENUM = ['JSTokenType', 'Meridiem']
+_ALLOW_ALL_UPPERCASE_ENUM = ['JSTokenType', 'Meridiem', 'NSType']
 
 
 def check_enum_casing(clean_lines, line_number, enum_state, error):

Modified: branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (291672 => 291673)


--- branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm	2022-03-22 17:57:12 UTC (rev 291672)
+++ branches/safari-613-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm	2022-03-22 17:57:16 UTC (rev 291673)
@@ -577,4 +577,33 @@
         [webView stringByEvaluatingJavaScript:@"IPC.webPageProxyID.toString()"].intValue);
 }
 
+TEST(IPCTestingAPI, CGColorInNSSecureCoding)
+{
+    auto archiver = adoptNS([[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]);
+
+    RetainPtr<id<NSKeyedArchiverDelegate, NSKeyedUnarchiverDelegate>> delegate = adoptNS([[NSClassFromString(@"WKSecureCodingArchivingDelegate") alloc] init]);
+    archiver.get().delegate = delegate.get();
+
+    auto payload = @{ @"SomeString" : static_cast<id>(adoptCF(CGColorCreateSRGB(0.2, 0.3, 0.4, 0.5)).get()) };
+    [archiver encodeObject:payload forKey:NSKeyedArchiveRootObjectKey];
+    [archiver finishEncoding];
+    [archiver setDelegate:nil];
+
+    auto data = "" encodedData];
+
+    auto unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nullptr]);
+    unarchiver.get().decodingFailurePolicy = NSDecodingFailurePolicyRaiseException;
+    unarchiver.get().delegate = delegate.get();
+
+    auto allowedClassSet = adoptNS([NSMutableSet new]);
+    [allowedClassSet addObject:NSDictionary.class];
+    [allowedClassSet addObject:NSString.class];
+    [allowedClassSet addObject:NSClassFromString(@"WKSecureCodingCGColorWrapper")];
+
+    id result = [unarchiver decodeObjectOfClasses:allowedClassSet.get() forKey:NSKeyedArchiveRootObjectKey];
+    EXPECT_TRUE([payload isEqual:result]);
+    [unarchiver finishDecoding];
+    unarchiver.get().delegate = nil;
+}
+
 #endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to