[Cocoa] Make it easier to encode NSObjects
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2018 21:13:47 +0000 (21:13 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Nov 2018 21:13:47 +0000 (21:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191948

Reviewed by Dean Jackson.

Source/WebCore:

* Modules/applepay/Payment.h: Changed the PKPayment * constructor to take a
RetainPtr<PKPayment>&& instead.
* Modules/applepay/PaymentContact.h: Ditto for PKContact.
* Modules/applepay/PaymentMerchantSession.h: Ditto for PKPaymentMerchantSession.
* Modules/applepay/PaymentMethod.h: Ditto for PKPaymentMethod.
* Modules/applepay/cocoa/PaymentCocoa.mm:
(WebCore::Payment::Payment): Moved definition out-of-line.
(WebCore::Payment::pkPayment const): Ditto.
* Modules/applepay/cocoa/PaymentContactCocoa.mm:
(WebCore::PaymentContact::PaymentContact): Ditto.
(WebCore::PaymentContact::pkContact const): Ditto.
* Modules/applepay/cocoa/PaymentMethodCocoa.mm:
(WebCore::PaymentMethod::PaymentMethod): Ditto.
(WebCore::PaymentMethod::pkPaymentMethod const): Ditto.

Source/WebCore/PAL:

* pal/spi/cocoa/PassKitSPI.h: Declared some classes that secretly conform to NSSecureCoding.

Source/WebKit:

It should be easier to encode objects that conform to NSSecureCoding for WebKit IPC. Right
now, several argument coders duplicate the logic for encoding and decoding objects using
NSKeyedArchiver and NSKeyedUnarchiver.

This patch adds encodeObject() and decodeObject() primitives for encoding and decoding using
Foundation keyed archiving. It then partially specializes ArgumentCoder for raw pointers and
RetainPtrs whose pointee conforms to NSSecureCoding to call these new primitives.

This allows us to use Encoder::operator<< to encode raw pointers or RetainPtrs and use
Decoder::operator>> to decode to an optional RetainPtr. By default, IPC::decode infers the
allowed class for decoding by calling `[T class]`. We can also specify the allowed classes
explicitly for containers and classes that are loaded at runtime.

* Shared/Cocoa/ArgumentCodersCocoa.h: Added.
* Shared/Cocoa/ArgumentCodersCocoa.mm: Added.
* Shared/Cocoa/DataDetectionResult.mm:
(WebKit::DataDetectionResult::encode const): Removed custom encoding code and used ArgumentCodersCocoa instead.
(WebKit::DataDetectionResult::decode): Ditto.
* Shared/Cocoa/WebCoreArgumentCodersCocoa.mm:
(IPC::ArgumentCoder<WebCore::Payment>::encode): Ditto.
(IPC::ArgumentCoder<WebCore::Payment>::decode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentAuthorizationResult>::decode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentContact>::encode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentContact>::decode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentMerchantSession>::encode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentMerchantSession>::decode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentMethod>::encode): Ditto.
(IPC::ArgumentCoder<WebCore::PaymentMethod>::decode): Ditto.
(IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::decode): Ditto.
* Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::description const): Added some needed namespaces due to unified source shuffling.
* Shared/WebCoreArgumentCoders.h: Modernized several decoders.
* Shared/ios/InteractionInformationAtPosition.mm:
(WebKit::InteractionInformationAtPosition::encode const): Removed custom encoding code and used ArgumentCodersCocoa instead.
(WebKit::InteractionInformationAtPosition::decode): Ditto.
* Shared/mac/WebCoreArgumentCodersMac.mm:
(IPC::ArgumentCoder<WebCore::ProtectionSpace>::encodePlatformData): Ditto.
(IPC::ArgumentCoder<WebCore::ProtectionSpace>::decodePlatformData): Ditto.
(IPC::ArgumentCoder<WebCore::Credential>::encodePlatformData): Ditto.
(IPC::ArgumentCoder<WebCore::Credential>::decodePlatformData): Ditto.
(IPC::ArgumentCoder<WebCore::MediaPlaybackTargetContext>::encodePlatformData): Ditto.
(IPC::ArgumentCoder<WebCore::MediaPlaybackTargetContext>::decodePlatformData): Ditto.
(IPC::deviceContextKey): Deleted.
* Shared/mac/WebHitTestResultData.mm:
(WebKit::WebHitTestResultData::platformEncode const): Ditto.
(WebKit::WebHitTestResultData::platformDecode): Ditto.
* SourcesCocoa.txt: Added ArgumentCodersCocoa.mm.
* WebKit.xcodeproj/project.pbxproj: Ditto.

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

22 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/applepay/Payment.h
Source/WebCore/Modules/applepay/PaymentContact.h
Source/WebCore/Modules/applepay/PaymentMerchantSession.h
Source/WebCore/Modules/applepay/PaymentMethod.h
Source/WebCore/Modules/applepay/cocoa/PaymentCocoa.mm
Source/WebCore/Modules/applepay/cocoa/PaymentContactCocoa.mm
Source/WebCore/Modules/applepay/cocoa/PaymentMethodCocoa.mm
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/pal/spi/cocoa/PassKitSPI.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.h [new file with mode: 0644]
Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm [new file with mode: 0644]
Source/WebKit/Shared/Cocoa/DataDetectionResult.mm
Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.mm
Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm
Source/WebKit/Shared/mac/WebCoreArgumentCodersMac.mm
Source/WebKit/Shared/mac/WebHitTestResultData.mm
Source/WebKit/SourcesCocoa.txt
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index 9917e8f..c77748e 100644 (file)
@@ -1,3 +1,25 @@
+2018-11-26  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] Make it easier to encode NSObjects
+        https://bugs.webkit.org/show_bug.cgi?id=191948
+
+        Reviewed by Dean Jackson.
+
+        * Modules/applepay/Payment.h: Changed the PKPayment * constructor to take a
+        RetainPtr<PKPayment>&& instead.
+        * Modules/applepay/PaymentContact.h: Ditto for PKContact.
+        * Modules/applepay/PaymentMerchantSession.h: Ditto for PKPaymentMerchantSession.
+        * Modules/applepay/PaymentMethod.h: Ditto for PKPaymentMethod.
+        * Modules/applepay/cocoa/PaymentCocoa.mm:
+        (WebCore::Payment::Payment): Moved definition out-of-line.
+        (WebCore::Payment::pkPayment const): Ditto.
+        * Modules/applepay/cocoa/PaymentContactCocoa.mm:
+        (WebCore::PaymentContact::PaymentContact): Ditto.
+        (WebCore::PaymentContact::pkContact const): Ditto.
+        * Modules/applepay/cocoa/PaymentMethodCocoa.mm:
+        (WebCore::PaymentMethod::PaymentMethod): Ditto.
+        (WebCore::PaymentMethod::pkPaymentMethod const): Ditto.
+
 2018-11-26  Daniel Bates  <dabates@apple.com>
 
         REGRESSION (r238078): Do not draw caps lock indicator when Strong Password button is shown
index 85f67be..36fb6fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,18 +37,13 @@ struct ApplePayPayment;
 
 class WEBCORE_EXPORT Payment {
 public:
-    Payment() = default;
-
-    explicit Payment(PKPayment *pkPayment)
-        : m_pkPayment(pkPayment)
-    {
-    }
-
-    virtual ~Payment() = default;
+    Payment();
+    explicit Payment(RetainPtr<PKPayment>&&);
+    virtual ~Payment();
 
     virtual ApplePayPayment toApplePayPayment(unsigned version) const;
 
-    PKPayment *pkPayment() const { return m_pkPayment.get(); }
+    PKPayment *pkPayment() const;
 
 private:
     RetainPtr<PKPayment> m_pkPayment;
index d0412d1..156fbf9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,17 +38,14 @@ struct ApplePayPaymentContact;
 
 class WEBCORE_EXPORT PaymentContact {
 public:
-    PaymentContact() = default;
-    explicit PaymentContact(PKContact *pkContact)
-        : m_pkContact(pkContact)
-    {
-    }
-    virtual ~PaymentContact() = default;
+    PaymentContact();
+    explicit PaymentContact(RetainPtr<PKContact>&&);
+    virtual ~PaymentContact();
 
     static PaymentContact fromApplePayPaymentContact(unsigned version, const ApplePayPaymentContact&);
     virtual ApplePayPaymentContact toApplePayPaymentContact(unsigned version) const;
 
-    PKContact *pkContact() const { return m_pkContact.get(); }
+    PKContact *pkContact() const;
 
 private:
     RetainPtr<PKContact> m_pkContact;
index 7ed6b21..daa7495 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,8 +42,8 @@ namespace WebCore {
 class PaymentMerchantSession {
 public:
     PaymentMerchantSession() = default;
-    explicit PaymentMerchantSession(PKPaymentMerchantSession *pkPaymentMerchantSession)
-        : m_pkPaymentMerchantSession(pkPaymentMerchantSession)
+    explicit PaymentMerchantSession(RetainPtr<PKPaymentMerchantSession>&& pkPaymentMerchantSession)
+        : m_pkPaymentMerchantSession { WTFMove(pkPaymentMerchantSession) }
     {
     }
 
index 9ce7baa..4afba2f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,17 +37,13 @@ struct ApplePayPaymentMethod;
 
 class WEBCORE_EXPORT PaymentMethod {
 public:
-    PaymentMethod() = default;
-    virtual ~PaymentMethod() = default;
-
-    explicit PaymentMethod(PKPaymentMethod *pkPaymentMethod)
-        : m_pkPaymentMethod(pkPaymentMethod)
-    {
-    }
+    PaymentMethod();
+    explicit PaymentMethod(RetainPtr<PKPaymentMethod>&&);
+    virtual ~PaymentMethod();
 
     virtual ApplePayPaymentMethod toApplePayPaymentMethod() const;
 
-    PKPaymentMethod *pkPaymentMethod() const { return m_pkPaymentMethod.get(); }
+    PKPaymentMethod *pkPaymentMethod() const;
 
 private:
     RetainPtr<PKPaymentMethod> m_pkPaymentMethod;
index 0b29d74..60a97e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -66,12 +66,26 @@ static ApplePayPayment convert(unsigned version, PKPayment *payment)
 
     return result;
 }
+    
+Payment::Payment() = default;
+
+Payment::Payment(RetainPtr<PKPayment>&& pkPayment)
+    : m_pkPayment { WTFMove(pkPayment) }
+{
+}
+
+Payment::~Payment() = default;
 
 ApplePayPayment Payment::toApplePayPayment(unsigned version) const
 {
     return convert(version, m_pkPayment.get());
 }
 
+PKPayment *Payment::pkPayment() const
+{
+    return m_pkPayment.get();
+}
+
 }
 
 #endif
index cc97fd5..e88284c 100644 (file)
@@ -208,6 +208,15 @@ static ApplePayPaymentContact convert(unsigned version, PKContact *contact)
     return result;
 }
 
+PaymentContact::PaymentContact() = default;
+
+PaymentContact::PaymentContact(RetainPtr<PKContact>&& pkContact)
+    : m_pkContact { WTFMove(pkContact) }
+{
+}
+
+PaymentContact::~PaymentContact() = default;
+
 PaymentContact PaymentContact::fromApplePayPaymentContact(unsigned version, const ApplePayPaymentContact& contact)
 {
     return PaymentContact(convert(version, contact).get());
@@ -218,6 +227,11 @@ ApplePayPaymentContact PaymentContact::toApplePayPaymentContact(unsigned version
     return convert(version, m_pkContact.get());
 }
 
+PKContact *PaymentContact::pkContact() const
+{
+    return m_pkContact.get();
+}
+
 }
 
 #endif
index 6ae68cd..a5c599a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -101,11 +101,25 @@ static ApplePayPaymentMethod convert(PKPaymentMethod *paymentMethod)
     return result;
 }
 
+PaymentMethod::PaymentMethod() = default;
+
+PaymentMethod::PaymentMethod(RetainPtr<PKPaymentMethod>&& pkPaymentMethod)
+    : m_pkPaymentMethod { WTFMove(pkPaymentMethod) }
+{
+}
+
+PaymentMethod::~PaymentMethod() = default;
+
 ApplePayPaymentMethod PaymentMethod::toApplePayPaymentMethod() const
 {
     return convert(m_pkPaymentMethod.get());
 }
 
+PKPaymentMethod *PaymentMethod::pkPaymentMethod() const
+{
+    return m_pkPaymentMethod.get();
+}
+
 }
 
 #endif
index 8494f27..0ee83bc 100644 (file)
@@ -1,3 +1,12 @@
+2018-11-26  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] Make it easier to encode NSObjects
+        https://bugs.webkit.org/show_bug.cgi?id=191948
+
+        Reviewed by Dean Jackson.
+
+        * pal/spi/cocoa/PassKitSPI.h: Declared some classes that secretly conform to NSSecureCoding.
+
 2018-11-24  Andy Estes  <aestes@apple.com>
 
         [Cocoa] SOFT_LINK_CLASS_FOR_{HEADER,SOURCE} should generate a more concise getter function
index 3ca39fa..18958e9 100644 (file)
@@ -327,10 +327,19 @@ void PKDrawApplePayButton(_Nonnull CGContextRef, CGRect drawRect, CGFloat scale,
 
 NS_ASSUME_NONNULL_BEGIN
 
+@interface PKContact () <NSSecureCoding>
+@end
+
 @interface PKPassLibrary ()
 - (void)openPaymentSetupForMerchantIdentifier:(NSString *)identifier domain:(NSString *)domain completion:(void(^)(BOOL success))completion;
 @end
 
+@interface PKPayment () <NSSecureCoding>
+@end
+
+@interface PKPaymentMethod () <NSSecureCoding>
+@end
+
 @interface PKPaymentRequest ()
 @property (nonatomic, strong) NSString *sourceApplicationBundleIdentifier;
 @property (nonatomic, strong) NSString *sourceApplicationSecondaryIdentifier;
index da8acc8..7be20ae 100644 (file)
@@ -1,3 +1,59 @@
+2018-11-26  Andy Estes  <aestes@apple.com>
+
+        [Cocoa] Make it easier to encode NSObjects
+        https://bugs.webkit.org/show_bug.cgi?id=191948
+
+        Reviewed by Dean Jackson.
+
+        It should be easier to encode objects that conform to NSSecureCoding for WebKit IPC. Right
+        now, several argument coders duplicate the logic for encoding and decoding objects using
+        NSKeyedArchiver and NSKeyedUnarchiver.
+
+        This patch adds encodeObject() and decodeObject() primitives for encoding and decoding using
+        Foundation keyed archiving. It then partially specializes ArgumentCoder for raw pointers and
+        RetainPtrs whose pointee conforms to NSSecureCoding to call these new primitives.
+
+        This allows us to use Encoder::operator<< to encode raw pointers or RetainPtrs and use
+        Decoder::operator>> to decode to an optional RetainPtr. By default, IPC::decode infers the
+        allowed class for decoding by calling `[T class]`. We can also specify the allowed classes
+        explicitly for containers and classes that are loaded at runtime.
+
+        * Shared/Cocoa/ArgumentCodersCocoa.h: Added.
+        * Shared/Cocoa/ArgumentCodersCocoa.mm: Added.
+        * Shared/Cocoa/DataDetectionResult.mm:
+        (WebKit::DataDetectionResult::encode const): Removed custom encoding code and used ArgumentCodersCocoa instead.
+        (WebKit::DataDetectionResult::decode): Ditto.
+        * Shared/Cocoa/WebCoreArgumentCodersCocoa.mm:
+        (IPC::ArgumentCoder<WebCore::Payment>::encode): Ditto.
+        (IPC::ArgumentCoder<WebCore::Payment>::decode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentAuthorizationResult>::decode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentContact>::encode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentContact>::decode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentMerchantSession>::encode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentMerchantSession>::decode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentMethod>::encode): Ditto.
+        (IPC::ArgumentCoder<WebCore::PaymentMethod>::decode): Ditto.
+        (IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::decode): Ditto.
+        * Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::description const): Added some needed namespaces due to unified source shuffling.
+        * Shared/WebCoreArgumentCoders.h: Modernized several decoders.
+        * Shared/ios/InteractionInformationAtPosition.mm:
+        (WebKit::InteractionInformationAtPosition::encode const): Removed custom encoding code and used ArgumentCodersCocoa instead.
+        (WebKit::InteractionInformationAtPosition::decode): Ditto.
+        * Shared/mac/WebCoreArgumentCodersMac.mm:
+        (IPC::ArgumentCoder<WebCore::ProtectionSpace>::encodePlatformData): Ditto.
+        (IPC::ArgumentCoder<WebCore::ProtectionSpace>::decodePlatformData): Ditto.
+        (IPC::ArgumentCoder<WebCore::Credential>::encodePlatformData): Ditto.
+        (IPC::ArgumentCoder<WebCore::Credential>::decodePlatformData): Ditto.
+        (IPC::ArgumentCoder<WebCore::MediaPlaybackTargetContext>::encodePlatformData): Ditto.
+        (IPC::ArgumentCoder<WebCore::MediaPlaybackTargetContext>::decodePlatformData): Ditto.
+        (IPC::deviceContextKey): Deleted.
+        * Shared/mac/WebHitTestResultData.mm:
+        (WebKit::WebHitTestResultData::platformEncode const): Ditto.
+        (WebKit::WebHitTestResultData::platformDecode): Ditto.
+        * SourcesCocoa.txt: Added ArgumentCodersCocoa.mm.
+        * WebKit.xcodeproj/project.pbxproj: Ditto.
+
 2018-11-26  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         CompletionHandler-based async IPC messages only work when the completion handler takes a single argument
diff --git a/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.h b/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.h
new file mode 100644 (file)
index 0000000..a2b1380
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "ArgumentCoders.h"
+
+#if PLATFORM(COCOA)
+
+#import <wtf/RetainPtr.h>
+
+namespace IPC {
+
+void encodeObject(Encoder&, id <NSSecureCoding>);
+std::optional<RetainPtr<id <NSSecureCoding>>> decodeObject(Decoder&, NSArray<Class> *allowedClasses);
+
+template<typename T> std::optional<RetainPtr<T>> decode(Decoder&, Class allowedClass);
+template<typename T> std::optional<RetainPtr<T>> decode(Decoder&, NSArray<Class> *allowedClasses = @[ [T class] ]);
+
+template<typename T>
+std::optional<RetainPtr<T>> decode(Decoder& decoder, Class allowedClass)
+{
+    return decode<T>(decoder, @[ allowedClass ]);
+}
+
+template<typename T>
+std::optional<RetainPtr<T>> decode(Decoder& decoder, NSArray<Class> *allowedClasses)
+{
+    auto result = decodeObject(decoder, allowedClasses);
+    if (!result)
+        return std::nullopt;
+
+    if (!*result)
+        return { nullptr };
+
+    id object = result->leakRef();
+    ASSERT([allowedClasses containsObject:[object class]]);
+    return { adoptNS(static_cast<T *>(object)) };
+}
+
+template<typename T> using ConformsToSecureCoding = std::is_convertible<T *, id <NSSecureCoding>>;
+
+template<typename T> struct ArgumentCoder<T *> {
+    template<typename U = T, std::enable_if_t<ConformsToSecureCoding<U>::value>* = nullptr>
+    static void encode(Encoder& encoder, U *object)
+    {
+        encodeObject(encoder, object);
+    }
+};
+
+template<typename T> struct ArgumentCoder<RetainPtr<T>> {
+    template <typename U = T, std::enable_if_t<ConformsToSecureCoding<U>::value>* = nullptr>
+    static void encode(Encoder& encoder, const RetainPtr<U>& object)
+    {
+        ArgumentCoder<U *>::encode(encoder, object.get());
+    }
+
+    template <typename U = T, std::enable_if_t<ConformsToSecureCoding<U>::value>* = nullptr>
+    static std::optional<RetainPtr<U>> decode(Decoder& decoder)
+    {
+        return IPC::decode<U>(decoder);
+    }
+};
+
+} // namespace IPC
+
+#endif // PLATFORM(COCOA)
diff --git a/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm b/Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm
new file mode 100644 (file)
index 0000000..ca2049b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+#import "ArgumentCodersCocoa.h"
+
+#if PLATFORM(COCOA)
+
+#import "ArgumentCodersCF.h"
+#import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
+
+namespace IPC {
+
+void encodeObject(Encoder& encoder, id <NSSecureCoding> object)
+{
+    auto archiver = secureArchiver();
+    [archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];
+    [archiver finishEncoding];
+
+    IPC::encode(encoder, (__bridge CFDataRef)[archiver encodedData]);
+}
+
+std::optional<RetainPtr<id <NSSecureCoding>>> decodeObject(Decoder& decoder, NSArray<Class> *allowedClasses)
+{
+    RetainPtr<CFDataRef> data;
+    if (!decode(decoder, data))
+        return std::nullopt;
+
+    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
+    @try {
+        id result = [unarchiver decodeObjectOfClasses:[NSSet setWithArray:allowedClasses] forKey:NSKeyedArchiveRootObjectKey];
+        ASSERT(!result || [result conformsToProtocol:@protocol(NSSecureCoding)]);
+        return { result };
+    } @catch (NSException *exception) {
+        LOG_ERROR("Failed to decode object of classes %@: %@", allowedClasses, exception);
+        return std::nullopt;
+    } @finally {
+        [unarchiver finishDecoding];
+    }
+}
+
+} // namespace IPC
+
+#endif // PLATFORM(COCOA)
index dafed9f..8de67a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "DataDetectionResult.h"
 
-#import "ArgumentCodersCF.h"
+#import "ArgumentCodersCocoa.h"
 #import "WebCoreArgumentCoders.h"
 #import <pal/spi/cocoa/DataDetectorsCoreSPI.h>
 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
@@ -41,27 +41,17 @@ namespace WebKit {
 
 void DataDetectionResult::encode(IPC::Encoder& encoder) const
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:results.get() forKey:@"dataDetectorResults"];
-    IPC::encode(encoder, (__bridge CFDataRef)archiver.get().encodedData);
+    encoder << results;
 }
 
 std::optional<DataDetectionResult> DataDetectionResult::decode(IPC::Decoder& decoder)
 {
-    RetainPtr<CFDataRef> data;
-    if (!IPC::decode(decoder, data))
+    auto results = IPC::decode<NSArray>(decoder, @[ [NSArray class], getDDScannerResultClass() ]);
+    if (!results)
         return std::nullopt;
 
     DataDetectionResult result;
-    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
-    @try {
-        result.results = [unarchiver decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], getDDScannerResultClass()] ] forKey:@"dataDetectorResults"];
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode NSArray of DDScanResult: %@", exception);
-        return std::nullopt;
-    }
-    
-    [unarchiver finishDecoding];
+    result.results = WTFMove(*results);
     return { WTFMove(result) };
 }
 #endif
index 1649d2e..0dd5d3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 
 #if ENABLE(APPLE_PAY)
 
+#import "ArgumentCodersCocoa.h"
 #import "DataReference.h"
 #import <WebCore/PaymentAuthorizationStatus.h>
 #import <pal/cocoa/PassKitSoftLink.h>
@@ -38,32 +39,16 @@ using namespace WebCore;
 
 void ArgumentCoder<WebCore::Payment>::encode(Encoder& encoder, const WebCore::Payment& payment)
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:payment.pkPayment() forKey:NSKeyedArchiveRootObjectKey];
-    [archiver finishEncoding];
-
-    auto data = archiver.get().encodedData;
-    encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
+    encoder << payment.pkPayment();
 }
 
-bool ArgumentCoder<WebCore::Payment>::decode(Decoder& decoder, WebCore::Payment& payment)
+std::optional<WebCore::Payment> ArgumentCoder<WebCore::Payment>::decode(Decoder& decoder)
 {
-    IPC::DataReference dataReference;
-    if (!decoder.decode(dataReference))
-        return false;
-
-    auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
-    auto unarchiver = secureUnarchiverFromData(data.get());
-    @try {
-        PKPayment *pkPayment = [unarchiver decodeObjectOfClass:PAL::getPKPaymentClass() forKey:NSKeyedArchiveRootObjectKey];
-        payment = Payment(pkPayment);
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode PKPayment: %@", exception);
-        return false;
-    }
+    auto payment = IPC::decode<PKPayment>(decoder, PAL::getPKPaymentClass());
+    if (!payment)
+        return std::nullopt;
 
-    [unarchiver finishDecoding];
-    return true;
+    return Payment { WTFMove(*payment) };
 }
 
 void ArgumentCoder<WebCore::PaymentAuthorizationResult>::encode(Encoder& encoder, const WebCore::PaymentAuthorizationResult& result)
@@ -83,38 +68,22 @@ std::optional<WebCore::PaymentAuthorizationResult> ArgumentCoder<WebCore::Paymen
     decoder >> errors;
     if (!errors)
         return std::nullopt;
-    
+
     return {{ WTFMove(*status), WTFMove(*errors) }};
 }
 
 void ArgumentCoder<WebCore::PaymentContact>::encode(Encoder& encoder, const WebCore::PaymentContact& paymentContact)
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:paymentContact.pkContact() forKey:NSKeyedArchiveRootObjectKey];
-    [archiver finishEncoding];
-
-    auto data = archiver.get().encodedData;
-    encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
+    encoder << paymentContact.pkContact();
 }
 
-bool ArgumentCoder<WebCore::PaymentContact>::decode(Decoder& decoder, WebCore::PaymentContact& paymentContact)
+std::optional<WebCore::PaymentContact> ArgumentCoder<WebCore::PaymentContact>::decode(Decoder& decoder)
 {
-    IPC::DataReference dataReference;
-    if (!decoder.decode(dataReference))
-        return false;
-
-    auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
-    auto unarchiver = secureUnarchiverFromData(data.get());
-    @try {
-        PKContact *pkContact = [unarchiver decodeObjectOfClass:PAL::getPKContactClass() forKey:NSKeyedArchiveRootObjectKey];
-        paymentContact = PaymentContact(pkContact);
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode PKContact: %@", exception);
-        return false;
-    }
+    auto contact = IPC::decode<PKContact>(decoder, PAL::getPKContactClass());
+    if (!contact)
+        return std::nullopt;
 
-    [unarchiver finishDecoding];
-    return true;
+    return WebCore::PaymentContact { WTFMove(*contact) };
 }
 
 void ArgumentCoder<WebCore::PaymentError>::encode(Encoder& encoder, const WebCore::PaymentError& error)
@@ -146,62 +115,30 @@ std::optional<WebCore::PaymentError> ArgumentCoder<WebCore::PaymentError>::decod
 
 void ArgumentCoder<WebCore::PaymentMerchantSession>::encode(Encoder& encoder, const WebCore::PaymentMerchantSession& paymentMerchantSession)
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:paymentMerchantSession.pkPaymentMerchantSession() forKey:NSKeyedArchiveRootObjectKey];
-    [archiver finishEncoding];
-
-    auto data = archiver.get().encodedData;
-    encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
+    encoder << paymentMerchantSession.pkPaymentMerchantSession();
 }
 
-bool ArgumentCoder<WebCore::PaymentMerchantSession>::decode(Decoder& decoder, WebCore::PaymentMerchantSession& paymentMerchantSession)
+std::optional<WebCore::PaymentMerchantSession> ArgumentCoder<WebCore::PaymentMerchantSession>::decode(Decoder& decoder)
 {
-    IPC::DataReference dataReference;
-    if (!decoder.decode(dataReference))
-        return false;
-
-    auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
-    auto unarchiver = secureUnarchiverFromData(data.get());
-    @try {
-        PKPaymentMerchantSession *pkPaymentMerchantSession = [unarchiver decodeObjectOfClass:PAL::getPKPaymentMerchantSessionClass() forKey:NSKeyedArchiveRootObjectKey];
-        paymentMerchantSession = PaymentMerchantSession(pkPaymentMerchantSession);
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode PKPaymentMerchantSession: %@", exception);
-        return false;
-    }
+    auto paymentMerchantSession = IPC::decode<PKPaymentMerchantSession>(decoder, PAL::getPKPaymentMerchantSessionClass());
+    if (!paymentMerchantSession)
+        return std::nullopt;
 
-    [unarchiver finishDecoding];
-    return true;
+    return WebCore::PaymentMerchantSession { WTFMove(*paymentMerchantSession) };
 }
 
 void ArgumentCoder<WebCore::PaymentMethod>::encode(Encoder& encoder, const WebCore::PaymentMethod& paymentMethod)
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:paymentMethod.pkPaymentMethod() forKey:NSKeyedArchiveRootObjectKey];
-    [archiver finishEncoding];
-
-    auto data = archiver.get().encodedData;
-    encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
+    encoder << paymentMethod.pkPaymentMethod();
 }
 
-bool ArgumentCoder<WebCore::PaymentMethod>::decode(Decoder& decoder, WebCore::PaymentMethod& paymentMethod)
+std::optional<WebCore::PaymentMethod> ArgumentCoder<WebCore::PaymentMethod>::decode(Decoder& decoder)
 {
-    IPC::DataReference dataReference;
-    if (!decoder.decode(dataReference))
-        return false;
-
-    auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
-    auto unarchiver = secureUnarchiverFromData(data.get());
-    @try {
-        PKPaymentMethod *pkPaymentMethod = [unarchiver decodeObjectOfClass:PAL::getPKPaymentMethodClass() forKey:NSKeyedArchiveRootObjectKey];
-        paymentMethod = PaymentMethod(pkPaymentMethod);
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode PKPayment: %@", exception);
-        return false;
-    }
+    auto paymentMethod = IPC::decode<PKPaymentMethod>(decoder, PAL::getPKPaymentMethodClass());
+    if (!paymentMethod)
+        return std::nullopt;
 
-    [unarchiver finishDecoding];
-    return true;
+    return PaymentMethod { WTFMove(*paymentMethod) };
 }
 
 void ArgumentCoder<WebCore::PaymentMethodUpdate>::encode(Encoder& encoder, const WebCore::PaymentMethodUpdate& update)
@@ -254,20 +191,22 @@ bool ArgumentCoder<ApplePaySessionPaymentRequest>::decode(Decoder& decoder, Appl
         return false;
     request.setRequiredBillingContactFields(requiredBillingContactFields);
 
-    PaymentContact billingContact;
-    if (!decoder.decode(billingContact))
+    std::optional<PaymentContact> billingContact;
+    decoder >> billingContact;
+    if (!billingContact)
         return false;
-    request.setBillingContact(billingContact);
+    request.setBillingContact(*billingContact);
 
     ApplePaySessionPaymentRequest::ContactFields requiredShippingContactFields;
     if (!decoder.decode((requiredShippingContactFields)))
         return false;
     request.setRequiredShippingContactFields(requiredShippingContactFields);
 
-    PaymentContact shippingContact;
-    if (!decoder.decode(shippingContact))
+    std::optional<PaymentContact> shippingContact;
+    decoder >> shippingContact;
+    if (!shippingContact)
         return false;
-    request.setShippingContact(shippingContact);
+    request.setShippingContact(*shippingContact);
 
     ApplePaySessionPaymentRequest::MerchantCapabilities merchantCapabilities;
     if (!decoder.decode(merchantCapabilities))
index 1c11ff8..c1e18c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -920,13 +920,13 @@ CString RemoteLayerTreeTransaction::description() const
             TextStream::GroupScope group(ts);
             ts << createdLayer.type <<" " << createdLayer.layerID;
             switch (createdLayer.type) {
-            case PlatformCALayer::LayerTypeAVPlayerLayer:
+            case WebCore::PlatformCALayer::LayerTypeAVPlayerLayer:
                 ts << " (context-id " << createdLayer.hostingContextID << ")";
                 break;
-            case PlatformCALayer::LayerTypeContentsProvidedLayer:
+            case WebCore::PlatformCALayer::LayerTypeContentsProvidedLayer:
                 ts << " (context-id " << createdLayer.hostingContextID << ")";
                 break;
-            case PlatformCALayer::LayerTypeCustom:
+            case WebCore::PlatformCALayer::LayerTypeCustom:
                 ts << " (context-id " << createdLayer.hostingContextID << ")";
                 break;
             default:
@@ -938,7 +938,7 @@ CString RemoteLayerTreeTransaction::description() const
     dumpChangedLayers(ts, m_changedLayerProperties);
 
     if (!m_destroyedLayerIDs.isEmpty())
-        ts.dumpProperty<Vector<GraphicsLayer::PlatformLayerID>>("destroyed-layers", m_destroyedLayerIDs);
+        ts.dumpProperty<Vector<WebCore::GraphicsLayer::PlatformLayerID>>("destroyed-layers", m_destroyedLayerIDs);
 
     if (m_editorState) {
         TextStream::GroupScope scope(ts);
index 0dfb6e8..0909b4d 100644 (file)
@@ -601,7 +601,7 @@ template<> struct ArgumentCoder<WebCore::ResourceLoadStatistics> {
 
 template<> struct ArgumentCoder<WebCore::Payment> {
     static void encode(Encoder&, const WebCore::Payment&);
-    static bool decode(Decoder&, WebCore::Payment&);
+    static std::optional<WebCore::Payment> decode(Decoder&);
 };
 
 template<> struct ArgumentCoder<WebCore::PaymentAuthorizationResult> {
@@ -611,7 +611,7 @@ template<> struct ArgumentCoder<WebCore::PaymentAuthorizationResult> {
 
 template<> struct ArgumentCoder<WebCore::PaymentContact> {
     static void encode(Encoder&, const WebCore::PaymentContact&);
-    static bool decode(Decoder&, WebCore::PaymentContact&);
+    static std::optional<WebCore::PaymentContact> decode(Decoder&);
 };
 
 template<> struct ArgumentCoder<WebCore::PaymentError> {
@@ -621,12 +621,12 @@ template<> struct ArgumentCoder<WebCore::PaymentError> {
 
 template<> struct ArgumentCoder<WebCore::PaymentMerchantSession> {
     static void encode(Encoder&, const WebCore::PaymentMerchantSession&);
-    static bool decode(Decoder&, WebCore::PaymentMerchantSession&);
+    static std::optional<WebCore::PaymentMerchantSession> decode(Decoder&);
 };
 
 template<> struct ArgumentCoder<WebCore::PaymentMethod> {
     static void encode(Encoder&, const WebCore::PaymentMethod&);
-    static bool decode(Decoder&, WebCore::PaymentMethod&);
+    static std::optional<WebCore::PaymentMethod> decode(Decoder&);
 };
 
 template<> struct ArgumentCoder<WebCore::PaymentMethodUpdate> {
index f1e0c3a..d0aa851 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "InteractionInformationAtPosition.h"
 
-#import "ArgumentCodersCF.h"
+#import "ArgumentCodersCocoa.h"
 #import "WebCoreArgumentCoders.h"
 #import <pal/spi/cocoa/DataDetectorsCoreSPI.h>
 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
@@ -76,10 +76,7 @@ void InteractionInformationAtPosition::encode(IPC::Encoder& encoder) const
     encoder << isDataDetectorLink;
     if (isDataDetectorLink) {
         encoder << dataDetectorIdentifier;
-        auto archiver = secureArchiver();
-        [archiver encodeObject:dataDetectorResults.get() forKey:@"dataDetectorResults"];
-
-        IPC::encode(encoder, reinterpret_cast<CFDataRef>(archiver.get().encodedData));
+        encoder << dataDetectorResults;
     }
 #endif
 #if ENABLE(DATALIST_ELEMENT)
@@ -173,19 +170,12 @@ bool InteractionInformationAtPosition::decode(IPC::Decoder& decoder, Interaction
     if (result.isDataDetectorLink) {
         if (!decoder.decode(result.dataDetectorIdentifier))
             return false;
-        RetainPtr<CFDataRef> data;
-        if (!IPC::decode(decoder, data))
-            return false;
-        
-        auto unarchiver = secureUnarchiverFromData((NSData *)data.get());
-        @try {
-            result.dataDetectorResults = [unarchiver decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], getDDScannerResultClass()] ] forKey:@"dataDetectorResults"];
-        } @catch (NSException *exception) {
-            LOG_ERROR("Failed to decode NSArray of DDScanResult: %@", exception);
+
+        auto dataDetectorResults = IPC::decode<NSArray>(decoder, @[ [NSArray class], getDDScannerResultClass() ]);
+        if (!dataDetectorResults)
             return false;
-        }
-        
-        [unarchiver finishDecoding];
+
+        result.dataDetectorResults = WTFMove(*dataDetectorResults);
     }
 #endif
 
index 8e36965..5fda7bf 100644 (file)
@@ -28,6 +28,7 @@
 #import "WebCoreArgumentCoders.h"
 
 #import "ArgumentCodersCF.h"
+#import "ArgumentCodersCocoa.h"
 #import "DataReference.h"
 #import <WebCore/CertificateInfo.h>
 #import <WebCore/ContentFilterUnblockHandler.h>
@@ -431,26 +432,16 @@ bool ArgumentCoder<WebCore::ResourceError>::decodePlatformData(Decoder& decoder,
 
 void ArgumentCoder<WebCore::ProtectionSpace>::encodePlatformData(Encoder& encoder, const WebCore::ProtectionSpace& space)
 {
-    auto archiver = secureArchiver();
-    [archiver encodeObject:space.nsSpace() forKey:@"protectionSpace"];
-    IPC::encode(encoder, (__bridge CFDataRef)archiver.get().encodedData);
+    encoder << space.nsSpace();
 }
 
 bool ArgumentCoder<WebCore::ProtectionSpace>::decodePlatformData(Decoder& decoder, WebCore::ProtectionSpace& space)
 {
-    RetainPtr<CFDataRef> data;
-    if (!IPC::decode(decoder, data))
+    auto platformData = IPC::decode<NSURLProtectionSpace>(decoder);
+    if (!platformData)
         return false;
 
-    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
-    @try {
-        if (RetainPtr<NSURLProtectionSpace> nsSpace = [unarchiver decodeObjectOfClass:[NSURLProtectionSpace class] forKey:@"protectionSpace"])
-            space = WebCore::ProtectionSpace(nsSpace.get());
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode NSURLProtectionSpace: %@", exception);
-    }
-
-    [unarchiver finishDecoding];
+    space = WebCore::ProtectionSpace { platformData->get() };
     return true;
 }
 
@@ -474,10 +465,7 @@ void ArgumentCoder<WebCore::Credential>::encodePlatformData(Encoder& encoder, co
     }
 
     encoder << false;
-
-    auto archiver = secureArchiver();
-    [archiver encodeObject:nsCredential forKey:@"credential"];
-    IPC::encode(encoder, (__bridge CFDataRef)archiver.get().encodedData);
+    encoder << nsCredential;
 }
 
 bool ArgumentCoder<WebCore::Credential>::decodePlatformData(Decoder& decoder, WebCore::Credential& credential)
@@ -509,19 +497,11 @@ bool ArgumentCoder<WebCore::Credential>::decodePlatformData(Decoder& decoder, We
         return true;
     }
 
-    RetainPtr<CFDataRef> data;
-    if (!IPC::decode(decoder, data))
+    auto nsCredential = IPC::decode<NSURLCredential>(decoder);
+    if (!nsCredential)
         return false;
 
-    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
-    @try {
-        if (RetainPtr<NSURLCredential> nsCredential = [unarchiver decodeObjectOfClass:[NSURLCredential class] forKey:@"credential"])
-            credential = WebCore::Credential(nsCredential.get());
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode NSURLCredential: %@", exception);
-    }
-
-    [unarchiver finishDecoding];
+    credential = WebCore::Credential { nsCredential->get() };
     return true;
 }
 
@@ -598,20 +578,10 @@ bool ArgumentCoder<WebCore::ContentFilterUnblockHandler>::decode(Decoder& decode
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
 
-static NSString *deviceContextKey()
-{
-    static NSString * const key = @"deviceContext";
-    return key;
-}
-
 void ArgumentCoder<WebCore::MediaPlaybackTargetContext>::encodePlatformData(Encoder& encoder, const WebCore::MediaPlaybackTargetContext& target)
 {
-    auto archiver = secureArchiver();
-
     if ([getAVOutputContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
-        [archiver encodeObject:target.avOutputContext() forKey:deviceContextKey()];
-
-    IPC::encode(encoder, (__bridge CFDataRef)archiver.get().encodedData);
+        encoder << target.avOutputContext();
 }
 
 bool ArgumentCoder<WebCore::MediaPlaybackTargetContext>::decodePlatformData(Decoder& decoder, WebCore::MediaPlaybackTargetContext& target)
@@ -619,23 +589,11 @@ bool ArgumentCoder<WebCore::MediaPlaybackTargetContext>::decodePlatformData(Deco
     if (![getAVOutputContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
         return false;
 
-    RetainPtr<CFDataRef> data;
-    if (!IPC::decode(decoder, data))
-        return false;
-
-    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
-
-    AVOutputContext *context = nil;
-    @try {
-        context = [unarchiver decodeObjectOfClass:getAVOutputContextClass() forKey:deviceContextKey()];
-    } @catch (NSException *exception) {
-        LOG_ERROR("The target picker being decoded is not an AVOutputContext.");
+    auto context = IPC::decode<AVOutputContext>(decoder, getAVOutputContextClass());
+    if (!context)
         return false;
-    }
 
-    target = WebCore::MediaPlaybackTargetContext(context);
-    
-    [unarchiver finishDecoding];
+    target = WebCore::MediaPlaybackTargetContext { context->get() };
     return true;
 }
 
index 588c5e5..5881343 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,10 +45,7 @@ void WebHitTestResultData::platformEncode(IPC::Encoder& encoder) const
     if (!hasActionContext)
         return;
 
-    auto archiver = secureArchiver();
-    [archiver encodeObject:detectedDataActionContext.get() forKey:@"actionContext"];
-
-    IPC::encode(encoder, (__bridge CFDataRef)archiver.get().encodedData);
+    encoder << detectedDataActionContext;
 
     encoder << detectedDataBoundingBox;
     encoder << detectedDataOriginatingPageOverlay;
@@ -69,19 +66,11 @@ bool WebHitTestResultData::platformDecode(IPC::Decoder& decoder, WebHitTestResul
         return true;
     ASSERT(DataDetectorsLibrary());
 
-    RetainPtr<CFDataRef> data;
-    if (!IPC::decode(decoder, data))
+    auto detectedDataActionContext = IPC::decode<DDActionContext>(decoder, getDDActionContextClass());
+    if (!detectedDataActionContext)
         return false;
 
-    auto unarchiver = secureUnarchiverFromData((__bridge NSData *)data.get());
-    @try {
-        hitTestResultData.detectedDataActionContext = [unarchiver decodeObjectOfClass:getDDActionContextClass() forKey:@"actionContext"];
-    } @catch (NSException *exception) {
-        LOG_ERROR("Failed to decode DDActionContext: %@", exception);
-        return false;
-    }
-    
-    [unarchiver finishDecoding];
+    hitTestResultData.detectedDataActionContext = WTFMove(*detectedDataActionContext);
 
     if (!decoder.decode(hitTestResultData.detectedDataBoundingBox))
         return false;
index 6ac8fec..8643dae 100644 (file)
@@ -122,6 +122,7 @@ Shared/Authentication/cocoa/AuthenticationManagerCocoa.mm
 
 Shared/Cocoa/APIDataCocoa.mm
 Shared/Cocoa/APIObject.mm
+Shared/Cocoa/ArgumentCodersCocoa.mm
 Shared/Cocoa/ChildProcessCocoa.mm
 Shared/Cocoa/CompletionHandlerCallChecker.mm
 Shared/Cocoa/DataDetectionResult.mm
index 2819069..61d9481 100644 (file)
                A13B3DA2207F39DE0090C58D /* MobileWiFiSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = A13B3DA1207F39DE0090C58D /* MobileWiFiSPI.h */; };
                A13DC682207AA6B20066EF72 /* WKApplicationStateTrackingView.h in Headers */ = {isa = PBXBuildFile; fileRef = A13DC680207AA6B20066EF72 /* WKApplicationStateTrackingView.h */; };
                A15EEDE61E301CEE000069B0 /* WKPasswordView.h in Headers */ = {isa = PBXBuildFile; fileRef = A15EEDE41E301CEE000069B0 /* WKPasswordView.h */; };
+               A175C44A21AA3171000037D0 /* ArgumentCodersCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = A175C44921AA3170000037D0 /* ArgumentCodersCocoa.h */; };
                A182D5B51BE6BD250087A7CC /* AccessibilityIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = A182D5B31BE6BD250087A7CC /* AccessibilityIOS.h */; };
                A19DD3C01D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A19DD3BF1D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h */; };
                A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A13DC681207AA6B20066EF72 /* WKApplicationStateTrackingView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKApplicationStateTrackingView.mm; path = ios/WKApplicationStateTrackingView.mm; sourceTree = "<group>"; };
                A15EEDE31E301CEE000069B0 /* WKPasswordView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKPasswordView.mm; path = ios/WKPasswordView.mm; sourceTree = "<group>"; };
                A15EEDE41E301CEE000069B0 /* WKPasswordView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKPasswordView.h; path = ios/WKPasswordView.h; sourceTree = "<group>"; };
+               A175C44921AA3170000037D0 /* ArgumentCodersCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentCodersCocoa.h; sourceTree = "<group>"; };
+               A175C44B21AA331B000037D0 /* ArgumentCodersCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ArgumentCodersCocoa.mm; sourceTree = "<group>"; };
                A182D5B21BE6BD250087A7CC /* AccessibilityIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityIOS.mm; sourceTree = "<group>"; };
                A182D5B31BE6BD250087A7CC /* AccessibilityIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityIOS.h; sourceTree = "<group>"; };
                A19DD3BF1D07D16800AC823B /* _WKWebViewPrintFormatterInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKWebViewPrintFormatterInternal.h; sourceTree = "<group>"; };
                        children = (
                                1A1EF1971A1D5B420023200A /* APIDataCocoa.mm */,
                                378E1A3B181ED6FF0031007A /* APIObject.mm */,
+                               A175C44921AA3170000037D0 /* ArgumentCodersCocoa.h */,
+                               A175C44B21AA331B000037D0 /* ArgumentCodersCocoa.mm */,
                                1A698F171E4910220064E881 /* ChildProcessCocoa.mm */,
                                37BEC4DF19491486008B4286 /* CompletionHandlerCallChecker.h */,
                                37BEC4DE19491486008B4286 /* CompletionHandlerCallChecker.mm */,
                                7A8A9D5A1EF13029009801AE /* APIInjectedBundleBundleClient.h in Headers */,
                                7A8A9D581EF119B0009801AE /* APIInjectedBundleClient.h in Headers */,
                                377512311DF0DEE2008A351C /* APIInjectedBundleEditorClient.h in Headers */,
-                               E4E57F6B21A83B1200345F3C /* RemoteLayerTreeNode.h in Headers */,
                                3769079E18F340A2001DFF04 /* APIInjectedBundleFormClient.h in Headers */,
                                7A3ACE1B1EEEF79B00A864A4 /* APIInjectedBundlePageLoaderClient.h in Headers */,
                                7A8A9D5C1EF14598009801AE /* APIInjectedBundlePageResourceLoadClient.h in Headers */,
                                1AEFD27911D16C81008219D3 /* ArgumentCoder.h in Headers */,
                                1AEFD2F711D1807B008219D3 /* ArgumentCoders.h in Headers */,
                                1AAF0C4A12B16334008E49E2 /* ArgumentCodersCF.h in Headers */,
+                               A175C44A21AA3171000037D0 /* ArgumentCodersCocoa.h in Headers */,
                                E179FD9C134D38060015B883 /* ArgumentCodersMac.h in Headers */,
                                CE1A0BD21A48E6C60054EF74 /* AssertionServicesSPI.h in Headers */,
                                C59C4A5918B81174007BDCB6 /* AssistedNodeInformation.h in Headers */,
                                1AB16AE21648656D00290D62 /* RemoteLayerTreeDrawingAreaProxy.h in Headers */,
                                0FF24A2E1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessages.h in Headers */,
                                1AA3D75C1651B44F008713D0 /* RemoteLayerTreeHost.h in Headers */,
+                               E4E57F6B21A83B1200345F3C /* RemoteLayerTreeNode.h in Headers */,
                                2DDE0AFA18298CC900F97EAA /* RemoteLayerTreePropertyApplier.h in Headers */,
                                0FF264A01A1FF9CC001FE759 /* RemoteLayerTreeScrollingPerformanceData.h in Headers */,
                                1AF1AC6C1651759E00C17D7F /* RemoteLayerTreeTransaction.h in Headers */,