Skip to content

Commit

Permalink
Generate serialization of CFDictionaryRef
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=268777

Reviewed by Brady Eidson.

And clean up the other Array/Dictionary serialization.
Remove some unneeded allocations from unneeded UniqueRef pointers.

* Source/WebKit/DerivedSources-input.xcfilelist:
* Source/WebKit/DerivedSources.make:
* Source/WebKit/Shared/Cocoa/CoreIPCArray.h:
(WebKit::CoreIPCArray::CoreIPCArray):
* Source/WebKit/Shared/Cocoa/CoreIPCArray.mm:
(WebKit::CoreIPCArray::CoreIPCArray):
(WebKit::CoreIPCArray::toID const):
* Source/WebKit/Shared/Cocoa/CoreIPCArray.serialization.in:
* Source/WebKit/Shared/Cocoa/CoreIPCCFType.h:
* Source/WebKit/Shared/Cocoa/CoreIPCDictionary.h:
* Source/WebKit/Shared/Cocoa/CoreIPCDictionary.mm:
(WebKit::CoreIPCDictionary::CoreIPCDictionary):
(WebKit::CoreIPCDictionary::createNSDictionaryIfNeeded const):
* Source/WebKit/Shared/Cocoa/CoreIPCDictionary.serialization.in:
* Source/WebKit/Shared/Cocoa/CoreIPCNSCFObject.h:
(WebKit::CoreIPCNSCFObject::value const):
* Source/WebKit/Shared/Cocoa/CoreIPCNSCFObject.serialization.in:
* Source/WebKit/Shared/cf/ArgumentCodersCF.cpp:
(IPC::ArgumentCoder<CFDictionaryRef>::encode): Deleted.
(IPC::ArgumentCoder<RetainPtr<CFDictionaryRef>>::decode): Deleted.
* Source/WebKit/Shared/cf/ArgumentCodersCF.h:
* Source/WebKit/Shared/cf/CFTypes.serialization.in:
* Source/WebKit/Shared/cf/CoreIPCCFArray.h:
(WebKit::CoreIPCCFArray::array const):
(WebKit::CoreIPCCFArray::CoreIPCCFArray): Deleted.
* Source/WebKit/Shared/cf/CoreIPCCFArray.mm:
(WebKit::CoreIPCCFArray::CoreIPCCFArray):
* Source/WebKit/Shared/cf/CoreIPCCFArray.serialization.in:
* Source/WebKit/Shared/cf/CoreIPCCFDictionary.h: Copied from Source/WebKit/Shared/cf/CoreIPCCFArray.h.
(WebKit::CoreIPCCFDictionary::vector const):
* Source/WebKit/Shared/cf/CoreIPCCFDictionary.mm: Copied from Source/WebKit/Shared/cf/CoreIPCCFArray.mm.
(WebKit::CoreIPCCFDictionary::CoreIPCCFDictionary):
(WebKit::CoreIPCCFDictionary::createCFDictionary const):
* Source/WebKit/Shared/cf/CoreIPCCFDictionary.serialization.in: Copied from Source/WebKit/Shared/cf/CoreIPCCFArray.serialization.in.
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/IPC/IPCSerialization.mm:
(operator==):
(dictionariesEqual):
(TEST):

Canonical link: https://commits.webkit.org/274192@main
  • Loading branch information
achristensen07 committed Feb 7, 2024
1 parent 0e458e8 commit 0d2bc11
Show file tree
Hide file tree
Showing 22 changed files with 245 additions and 109 deletions.
2 changes: 1 addition & 1 deletion Source/WebKit/DerivedSources-input.xcfilelist
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ $(PROJECT_DIR)/Shared/Cocoa/CacheStoragePolicy.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCAVOutputContext.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCArray.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCAuditToken.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCCFArray.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCCFType.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCCFURL.serialization.in
$(PROJECT_DIR)/Shared/Cocoa/CoreIPCColor.serialization.in
Expand Down Expand Up @@ -441,6 +440,7 @@ $(PROJECT_DIR)/Shared/XR/XRSystem.serialization.in
$(PROJECT_DIR)/Shared/cf/CFTypes.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCBoolean.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCCFArray.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCCFDictionary.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCCGColorSpace.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCNumber.serialization.in
$(PROJECT_DIR)/Shared/cf/CoreIPCSecCertificate.serialization.in
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/DerivedSources.make
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ SERIALIZATION_DESCRIPTION_FILES = \
Shared/cf/CFTypes.serialization.in \
Shared/cf/CoreIPCBoolean.serialization.in \
Shared/cf/CoreIPCCFArray.serialization.in \
Shared/cf/CoreIPCCFDictionary.serialization.in \
Shared/cf/CoreIPCCGColorSpace.serialization.in \
Shared/cf/CoreIPCNumber.serialization.in \
Shared/cf/CoreIPCSecCertificate.serialization.in \
Expand Down
5 changes: 2 additions & 3 deletions Source/WebKit/Shared/Cocoa/CoreIPCArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#include "ArgumentCodersCocoa.h"
#include <wtf/RetainPtr.h>
#include <wtf/UniqueRef.h>

namespace WebKit {

Expand All @@ -48,12 +47,12 @@ class CoreIPCArray {
private:
friend struct IPC::ArgumentCoder<CoreIPCArray, void>;

CoreIPCArray(Vector<UniqueRef<CoreIPCNSCFObject>>&& array)
CoreIPCArray(Vector<CoreIPCNSCFObject>&& array)
: m_array(WTFMove(array))
{
}

Vector<UniqueRef<CoreIPCNSCFObject>> m_array;
Vector<CoreIPCNSCFObject> m_array;
};

} // namespace WebKit
Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/Shared/Cocoa/CoreIPCArray.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@
for (id value in array) {
if (!IPC::isSerializableValue(value))
continue;
m_array.append(WTF::makeUniqueRef<CoreIPCNSCFObject>(value));
m_array.append(CoreIPCNSCFObject(value));
}
}

RetainPtr<id> CoreIPCArray::toID() const
{
auto result = adoptNS([[NSMutableArray alloc] initWithCapacity:m_array.size()]);
for (auto& object : m_array)
[result addObject:object->toID().get()];
[result addObject:object.toID().get()];
return result;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/Shared/Cocoa/CoreIPCArray.serialization.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
webkit_platform_headers: "CoreIPCArray.h"

[WebKitPlatform] class WebKit::CoreIPCArray {
Vector<UniqueRef<WebKit::CoreIPCNSCFObject>> m_array;
Vector<WebKit::CoreIPCNSCFObject> m_array;
}

#endif // PLATFORM(COCOA)
1 change: 0 additions & 1 deletion Source/WebKit/Shared/Cocoa/CoreIPCCFType.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
namespace WebKit {

class CoreIPCCFType {
WTF_MAKE_FAST_ALLOCATED;
public:
CoreIPCCFType(CFTypeRef cfType)
: m_cfType(cfType)
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/Shared/Cocoa/CoreIPCDictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CoreIPCDictionary {
private:
friend struct IPC::ArgumentCoder<CoreIPCDictionary, void>;

using ValueType = Vector<KeyValuePair<UniqueRef<CoreIPCNSCFObject>, UniqueRef<CoreIPCNSCFObject>>>;
using ValueType = Vector<KeyValuePair<CoreIPCNSCFObject, CoreIPCNSCFObject>>;

CoreIPCDictionary(ValueType&& keyValuePairs)
: m_keyValuePairs(WTFMove(keyValuePairs))
Expand Down
4 changes: 2 additions & 2 deletions Source/WebKit/Shared/Cocoa/CoreIPCDictionary.mm
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
if (!IPC::isSerializableValue(key) || !IPC::isSerializableValue(value))
continue;

m_keyValuePairs.append({ WTF::makeUniqueRef<CoreIPCNSCFObject>(key), WTF::makeUniqueRef<CoreIPCNSCFObject>(value) });
m_keyValuePairs.append({ CoreIPCNSCFObject(key), CoreIPCNSCFObject(value) });
}
}

Expand Down Expand Up @@ -115,7 +115,7 @@
if (!m_nsDictionary) {
auto result = adoptNS([[NSMutableDictionary alloc] initWithCapacity:m_keyValuePairs.size()]);
for (auto& keyValuePair : m_keyValuePairs)
[result setObject:keyValuePair.value->toID().get() forKey:keyValuePair.key->toID().get()];
[result setObject:keyValuePair.value.toID().get() forKey:keyValuePair.key.toID().get()];
m_nsDictionary = WTFMove(result);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ webkit_platform_headers: "CoreIPCDictionary.h"

[WebKitPlatform] class WebKit::CoreIPCDictionary {
[NotSerialized] RetainPtr<NSDictionary> m_nsDictionary;
Vector<KeyValuePair<UniqueRef<WebKit::CoreIPCNSCFObject>, UniqueRef<WebKit::CoreIPCNSCFObject>>> m_keyValuePairs;
Vector<KeyValuePair<WebKit::CoreIPCNSCFObject, WebKit::CoreIPCNSCFObject>> m_keyValuePairs;
}

#endif // PLATFORM(COCOA)
7 changes: 2 additions & 5 deletions Source/WebKit/Shared/Cocoa/CoreIPCNSCFObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,16 @@ using ObjectValue = std::variant<
>;

class CoreIPCNSCFObject {
WTF_MAKE_FAST_ALLOCATED;
public:
CoreIPCNSCFObject(id);
CoreIPCNSCFObject(UniqueRef<ObjectValue>&&);

RetainPtr<id> toID() const;

static bool valueIsAllowed(IPC::Decoder&, ObjectValue&);

const UniqueRef<ObjectValue>& value() const { return m_value; }
private:
friend struct IPC::ArgumentCoder<CoreIPCNSCFObject, void>;

CoreIPCNSCFObject(UniqueRef<ObjectValue>&&);

UniqueRef<ObjectValue> m_value;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
webkit_platform_headers: "ArgumentCodersCocoa.h" "ArgumentCodersCF.h" "CoreIPCNSCFObject.h"

[WebKitPlatform] class WebKit::CoreIPCNSCFObject {
[Validator='WebKit::CoreIPCNSCFObject::valueIsAllowed(decoder, *m_value)'] UniqueRef<WebKit::ObjectValue> m_value;
[Validator='WebKit::CoreIPCNSCFObject::valueIsAllowed(decoder, *value)'] UniqueRef<WebKit::ObjectValue> value();
}

#endif // USE(CF)
72 changes: 0 additions & 72 deletions Source/WebKit/Shared/cf/ArgumentCodersCF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,78 +336,6 @@ std::optional<RetainPtr<CFCharacterSetRef>> ArgumentCoder<RetainPtr<CFCharacterS
return WTFMove(characterSet);
}

template<typename Encoder>
void ArgumentCoder<CFDictionaryRef>::encode(Encoder& encoder, CFDictionaryRef dictionary)
{
if (!dictionary) {
encoder << true;
return;
}

encoder << false;

CFIndex size = CFDictionaryGetCount(dictionary);
Vector<CFTypeRef, 32> keys(size);
Vector<CFTypeRef, 32> values(size);

CFDictionaryGetKeysAndValues(dictionary, keys.data(), values.data());

HashSet<CFTypeRef> invalidKeys;
for (CFIndex i = 0; i < size; ++i) {
ASSERT(keys[i]);
ASSERT(values[i]);

// Ignore keys/values we don't support.
if (typeFromCFTypeRef(keys[i]) == CFType::Unknown || typeFromCFTypeRef(values[i]) == CFType::Unknown)
invalidKeys.add(keys[i]);
}

encoder << static_cast<uint64_t>(size - invalidKeys.size());

for (CFIndex i = 0; i < size; ++i) {
if (invalidKeys.contains(keys[i]))
continue;

encoder << keys[i] << values[i];
}
}

template void ArgumentCoder<CFDictionaryRef>::encode<Encoder>(Encoder&, CFDictionaryRef);
template void ArgumentCoder<CFDictionaryRef>::encode<StreamConnectionEncoder>(StreamConnectionEncoder&, CFDictionaryRef);

std::optional<RetainPtr<CFDictionaryRef>> ArgumentCoder<RetainPtr<CFDictionaryRef>>::decode(Decoder& decoder)
{
std::optional<bool> isNull;
decoder >> isNull;
if (!isNull)
return std::nullopt;

if (*isNull)
return {{ nullptr }};

std::optional<uint64_t> size;
decoder >> size;
if (!size)
return std::nullopt;

RetainPtr<CFMutableDictionaryRef> dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
for (uint64_t i = 0; i < *size; ++i) {
std::optional<RetainPtr<CFTypeRef>> key;
decoder >> key;
if (!key || !*key)
return std::nullopt;

std::optional<RetainPtr<CFTypeRef>> value;
decoder >> value;
if (!value || !*value)
return std::nullopt;

CFDictionarySetValue(dictionary.get(), key->get(), value->get());
}

return WTFMove(dictionary);
}

#if HAVE(SEC_ACCESS_CONTROL)
template<typename Encoder>
void ArgumentCoder<SecAccessControlRef>::encode(Encoder& encoder, SecAccessControlRef accessControl)
Expand Down
7 changes: 0 additions & 7 deletions Source/WebKit/Shared/cf/ArgumentCodersCF.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,6 @@ template<> struct ArgumentCoder<RetainPtr<CFCharacterSetRef>> : CFRetainPtrArgum
static std::optional<RetainPtr<CFCharacterSetRef>> decode(Decoder&);
};

template<> struct ArgumentCoder<CFDictionaryRef> {
template<typename Encoder> static void encode(Encoder&, CFDictionaryRef);
};
template<> struct ArgumentCoder<RetainPtr<CFDictionaryRef>> : CFRetainPtrArgumentCoder<CFDictionaryRef> {
static std::optional<RetainPtr<CFDictionaryRef>> decode(Decoder&);
};

#if HAVE(SEC_ACCESS_CONTROL)
template<> struct ArgumentCoder<SecAccessControlRef> {
template<typename Encoder> static void encode(Encoder&, SecAccessControlRef);
Expand Down
3 changes: 3 additions & 0 deletions Source/WebKit/Shared/cf/CFTypes.serialization.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
[WebKitPlatform, CustomHeader, AdditionalEncoder=StreamConnectionEncoder, ToCFMethod=result->createCFArray()] CFArrayRef wrapped by WebKit::CoreIPCCFArray {
}

[WebKitPlatform, CustomHeader, AdditionalEncoder=StreamConnectionEncoder, ToCFMethod=result->createCFDictionary()] CFDictionaryRef wrapped by WebKit::CoreIPCCFDictionary {
}

[WebKitPlatform, CustomHeader, AdditionalEncoder=StreamConnectionEncoder, ToCFMethod=result->createBoolean()] CFBooleanRef wrapped by WebKit::CoreIPCBoolean {
}

Expand Down
9 changes: 4 additions & 5 deletions Source/WebKit/Shared/cf/CoreIPCCFArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#if USE(CF)

#include <wtf/RetainPtr.h>
#include <wtf/UniqueRef.h>
#include <wtf/Vector.h>

namespace WebKit {
Expand All @@ -38,12 +37,12 @@ class CoreIPCCFType;
class CoreIPCCFArray {
public:
CoreIPCCFArray(CFArrayRef);
CoreIPCCFArray(Vector<UniqueRef<CoreIPCCFType>>&& array)
: m_array(WTFMove(array)) { }
CoreIPCCFArray(Vector<CoreIPCCFType>&&);
~CoreIPCCFArray();
RetainPtr<CFArrayRef> createCFArray() const;
const Vector<UniqueRef<CoreIPCCFType>>& array() const { return m_array; }
const Vector<CoreIPCCFType>& array() const { return m_array; }
private:
Vector<UniqueRef<CoreIPCCFType>> m_array;
Vector<CoreIPCCFType> m_array;
};

} // namespace WebKit
Expand Down
7 changes: 6 additions & 1 deletion Source/WebKit/Shared/cf/CoreIPCCFArray.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@

namespace WebKit {

CoreIPCCFArray::CoreIPCCFArray(Vector<CoreIPCCFType>&& array)
: m_array(WTFMove(array)) { }

CoreIPCCFArray::~CoreIPCCFArray() = default;

CoreIPCCFArray::CoreIPCCFArray(CFArrayRef array)
{
CFIndex count = array ? CFArrayGetCount(array) : 0;
for (CFIndex i = 0; i < count; i++) {
CFTypeRef element = CFArrayGetValueAtIndex(array, i);
if (IPC::typeFromCFTypeRef(element) == IPC::CFType::Unknown)
continue;
m_array.append(makeUniqueRef<CoreIPCCFType>(element));
m_array.append(CoreIPCCFType(element));
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/Shared/cf/CoreIPCCFArray.serialization.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
webkit_platform_headers: "CoreIPCCFArray.h"

[WebKitPlatform, AdditionalEncoder=StreamConnectionEncoder] class WebKit::CoreIPCCFArray {
Vector<UniqueRef<WebKit::CoreIPCCFType>> array();
Vector<WebKit::CoreIPCCFType> array();
}

#endif
53 changes: 53 additions & 0 deletions Source/WebKit/Shared/cf/CoreIPCCFDictionary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2024 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.
*/

#pragma once

#if USE(CF)

#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>

namespace WebKit {

class CoreIPCCFType;

class CoreIPCCFDictionary {
public:
using KeyValueVector = Vector<KeyValuePair<CoreIPCCFType, CoreIPCCFType>>;

CoreIPCCFDictionary(CFDictionaryRef);
CoreIPCCFDictionary(CoreIPCCFDictionary&&);
CoreIPCCFDictionary(std::unique_ptr<KeyValueVector>&&);
~CoreIPCCFDictionary();
RetainPtr<CFDictionaryRef> createCFDictionary() const;
const std::unique_ptr<KeyValueVector>& vector() const { return m_vector; }
private:
std::unique_ptr<KeyValueVector> m_vector;
};

} // namespace WebKit

#endif // USE(CF)
Loading

0 comments on commit 0d2bc11

Please sign in to comment.