Adopt NSSecureCoding everywhere

This commit is contained in:
Max Radermacher 2026-01-12 17:31:31 -06:00 committed by GitHub
parent a64fd10fcc
commit 87dc2f1e0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
160 changed files with 742 additions and 1371 deletions

View File

@ -511,34 +511,82 @@ class TypeInfo:
)
elif self.should_use_blob:
blob_name = "%sSerialized" % (str(value_name),)
if is_optional or did_force_optional:
if is_optional:
serialized_statement = "let %s: Data? = %s" % (
blob_name,
value_expr,
)
elif did_force_optional:
serialized_statement = f'let {blob_name}: Data = try {value_expr} ?? {{ () -> Data in throw SDSError.missingRequiredField(fieldName: "{value_name}") }}()'
else:
serialized_statement = "let %s: Data = %s" % (
blob_name,
value_expr,
)
from_name = "$0" if is_optional else blob_name
swift_type = self._swift_type
if swift_type == "[InfoMessageUserInfoKey: AnyObject]":
decode_statement = (
'try SDSDeserialization.unarchivedInfoDictionary(from: %s)'
% (
from_name,
)
)
elif ": " in swift_type:
assert swift_type.startswith("[")
assert swift_type.endswith("]")
divider_index = swift_type.index(": ")
key_type = swift_type[1:divider_index]
value_type = swift_type[divider_index + 2:-1]
decode_statement = (
'try SDSDeserialization.unarchivedDictionary(ofKeyClass: %s.self, objectClass: %s.self, from: %s)'
% (
key_type,
value_type,
from_name,
)
)
elif swift_type.startswith("["):
assert swift_type.endswith("]")
array_type = self._swift_type[1:-1]
objc_types = {
"String": "NSString",
}
objc_type = objc_types.get(array_type, array_type)
decode_statement = (
'try SDSDeserialization.unarchivedArrayOfObjects(ofClass: %s.self, from: %s)'
% (
objc_type,
from_name,
)
)
if array_type in objc_types:
decode_statement += ' as ' + self._swift_type
else:
decode_statement = (
'try SDSDeserialization.unarchivedObject(ofClass: %s.self, from: %s)'
% (
self._swift_type,
from_name,
)
)
if is_optional:
value_statement = (
'let %s: %s? = try SDSDeserialization.optionalUnarchive(%s, name: "%s")'
'let %s: %s? = try %s.map({ %s })'
% (
value_name,
self._swift_type,
blob_name,
value_name,
decode_statement,
)
)
else:
value_statement = (
'let %s: %s = try SDSDeserialization.unarchive(%s, name: "%s")'
'let %s: %s = %s'
% (
value_name,
self._swift_type,
blob_name,
value_name,
decode_statement,
)
)
return [

View File

@ -731,7 +731,6 @@
507B69122C5044F800F1C6D7 /* LinkPreviewGroupLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A95517271B510400B05242 /* LinkPreviewGroupLink.swift */; };
507C6AF52ED10BD900A7C74C /* RegisteredState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507C6AF42ED10BD900A7C74C /* RegisteredState.swift */; };
507CD5E529660D5100E47DAC /* ServiceId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CD5E429660D5100E47DAC /* ServiceId.swift */; };
507E1BDF2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507E1BDE2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift */; };
508622AD2D026F5200931BF9 /* CanonicalPhoneNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508622AC2D026F5200931BF9 /* CanonicalPhoneNumberTest.swift */; };
508C72242C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508C72232C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift */; };
508F0346296F72F4001D88D0 /* CustomCellBackgroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508F0345296F72F4001D88D0 /* CustomCellBackgroundColor.swift */; };
@ -4918,7 +4917,6 @@
507D614B2BE433EE00DA7BA3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = translations/be.lproj/InfoPlist.strings; sourceTree = "<group>"; };
507D614C2BE433EE00DA7BA3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = translations/be.lproj/Localizable.strings; sourceTree = "<group>"; };
507D614D2BE433EE00DA7BA3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = be; path = translations/be.lproj/PluralAware.stringsdict; sourceTree = "<group>"; };
507E1BDE2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSKeyedUnarchiver+SSK.swift"; sourceTree = "<group>"; };
508347052AABBF9900DD2EC0 /* ProfileManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileManagerTest.swift; sourceTree = "<group>"; };
508622AC2D026F5200931BF9 /* CanonicalPhoneNumberTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CanonicalPhoneNumberTest.swift; sourceTree = "<group>"; };
508C72232C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSOutgoingResendResponseTest.swift; sourceTree = "<group>"; };
@ -15191,7 +15189,6 @@
721BC7EB2BC8253600648981 /* MimeTypeUtil.swift */,
F9C5CB57289453B200548EEE /* ModelReadCache.swift */,
D9C7CECE28ECC043001E87B6 /* NSAttributedString+SSK.swift */,
507E1BDE2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift */,
F9C5CB39289453B200548EEE /* NSNotificationCenter+OWS.swift */,
50502C7B2EF1D2B1007A64EB /* NSObject+SSK.swift */,
F9C5CB1F289453B200548EEE /* NSRegularExpression+SSK.swift */,
@ -19118,7 +19115,6 @@
664657412AC4FB720099DE1C /* NotificationPresenter.swift in Sources */,
725465612BA033E200EABFD2 /* NotificationPresenterImpl.swift in Sources */,
D9C7CECF28ECC043001E87B6 /* NSAttributedString+SSK.swift in Sources */,
507E1BDF2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift in Sources */,
F9C5CE0B289453B400548EEE /* NSNotificationCenter+OWS.swift in Sources */,
50502C7C2EF1D2B1007A64EB /* NSObject+SSK.swift in Sources */,
66F2CE212A3CBE4A00519342 /* NSRangedValue.swift in Sources */,

View File

@ -15,11 +15,6 @@ public class DateHeaderInteraction: TSInteraction {
.dateHeader
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public init(thread: TSThread, timestamp: UInt64) {
// Include timestamp in uniqueId to ensure invariant that
// interactions don't move in the chat history ordering.

View File

@ -15,11 +15,6 @@ public class DefaultDisappearingMessageTimerInteraction: TSInteraction {
.defaultDisappearingMessageTimer
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public init(thread: TSThread, timestamp: UInt64) {
// Include timestamp in uniqueId to ensure invariant that
// interactions don't move in the chat history ordering.

View File

@ -15,11 +15,6 @@ public class ThreadDetailsInteraction: TSInteraction {
.threadDetails
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public init(thread: TSThread, timestamp: UInt64) {
// Include timestamp in uniqueId to ensure invariant that
// interactions don't move in the chat history ordering.

View File

@ -16,11 +16,6 @@ public class TypingIndicatorInteraction: TSInteraction {
.typingIndicator
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public let address: SignalServiceAddress
public init(thread: TSThread, timestamp: UInt64, address: SignalServiceAddress) {

View File

@ -15,11 +15,6 @@ public class UnknownThreadWarningInteraction: TSInteraction {
.unknownThreadWarning
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public init(thread: TSThread, timestamp: UInt64) {
// Include timestamp in uniqueId to ensure invariant that
// interactions don't move in the chat history ordering.

View File

@ -15,11 +15,6 @@ public class UnreadIndicatorInteraction: TSInteraction {
.unreadIndicator
}
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public init(thread: TSThread, timestamp: UInt64, receivedAtTimestamp: UInt64) {
// Include timestamp in uniqueId to ensure invariant that
// interactions don't move in the chat history ordering.

View File

@ -112,11 +112,7 @@ struct InfoMessageGroupUpdateMigrator {
guard
let infoMessageUserInfoBlob = infoMessage.infoMessageUserInfoBlob,
let infoMessageUserInfo = try? NSKeyedUnarchiver.unarchivedObject(
ofClass: NSDictionary.self,
from: infoMessageUserInfoBlob,
requiringSecureCoding: false,
) as? [InfoMessageUserInfoKey: Any]
let infoMessageUserInfo = try? SDSDeserialization.unarchivedInfoDictionary(from: infoMessageUserInfoBlob)
else {
// Missing or failed-to-unarchive infoMessageUserInfo: skip
// this interaction.
@ -149,7 +145,7 @@ struct InfoMessageGroupUpdateMigrator {
]
let newInfoMessageUserInfoBlob = try! NSKeyedArchiver.archivedData(
withRootObject: newInfoMessageUserInfo,
requiringSecureCoding: false,
requiringSecureCoding: true,
)
try? tx.database.execute(

View File

@ -227,10 +227,6 @@ private class MockIncomingMessage: TSIncomingMessage {
super.init(incomingMessageWithBuilder: builder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var shouldBeSaved: Bool {
return false
}

View File

@ -98,16 +98,12 @@ class InfoMessageGroupUpdateMigratorTest: SignalBaseTest {
private func encode(_ infoMessageUserInfo: [InfoMessageUserInfoKey: Any]) -> Data {
return try! NSKeyedArchiver.archivedData(
withRootObject: infoMessageUserInfo,
requiringSecureCoding: false,
requiringSecureCoding: true,
)
}
private func decode(_ data: Data) -> [InfoMessageUserInfoKey: Any] {
return try! NSKeyedUnarchiver.unarchivedObject(
ofClass: NSDictionary.self,
from: data,
requiringSecureCoding: false,
) as! [InfoMessageUserInfoKey: Any]
private func decode(_ data: Data) -> [InfoMessageUserInfoKey: AnyObject] {
return try! SDSDeserialization.unarchivedInfoDictionary(from: data)
}
}

View File

@ -59,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN
timestamp:(uint64_t)timestamp
uniqueThreadId:(NSString *)uniqueThreadId NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
- (instancetype)initWithJoinedMemberAcis:(NSArray<AciObjC *> *)joinedMemberAcis
creatorAci:(nullable AciObjC *)creatorAci

View File

@ -80,40 +80,6 @@ NS_ASSUME_NONNULL_BEGIN
// --- CODE GENERATION MARKER
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSString *creatorUuid = self.creatorUuid;
if (creatorUuid != nil) {
[coder encodeObject:creatorUuid forKey:@"creatorUuid"];
}
NSString *eraId = self.eraId;
if (eraId != nil) {
[coder encodeObject:eraId forKey:@"eraId"];
}
[coder encodeObject:[self valueForKey:@"hasEnded"] forKey:@"hasEnded"];
NSArray *joinedMemberUuids = self.joinedMemberUuids;
if (joinedMemberUuids != nil) {
[coder encodeObject:joinedMemberUuids forKey:@"joinedMemberUuids"];
}
[coder encodeObject:[self valueForKey:@"read"] forKey:@"read"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_creatorUuid = [coder decodeObjectOfClass:[NSString class] forKey:@"creatorUuid"];
self->_eraId = [coder decodeObjectOfClass:[NSString class] forKey:@"eraId"];
self->_hasEnded = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"hasEnded"] boolValue];
self->_joinedMemberUuids = [coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], [NSString class] ]]
forKey:@"joinedMemberUuids"];
self->_read = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"read"] boolValue];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];

View File

@ -9,6 +9,8 @@
/// Not to be confused with an ``OWSGroupCallMessage``.
@objc(OWSOutgoingGroupCallMessage)
public final class OutgoingGroupCallUpdateMessage: TSOutgoingMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.eraId = coder.decodeObject(of: NSString.self, forKey: "eraId") as String?
super.init(coder: coder)

View File

@ -67,7 +67,7 @@ NSString *NSStringFromCallType(RPRecentCallType callType);
timestamp:(uint64_t)timestamp
uniqueThreadId:(NSString *)uniqueThreadId NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
- (instancetype)initWithCallType:(RPRecentCallType)callType
offerType:(TSRecentCallOfferType)offerType

View File

@ -41,12 +41,8 @@ NSString *NSStringFromCallType(RPRecentCallType callType)
}
}
NSUInteger TSCallCurrentSchemaVersion = 1;
@interface TSCall ()
@property (nonatomic, readonly) NSUInteger callSchemaVersion;
@property (nonatomic) TSRecentCallOfferType offerType;
@end
@ -68,7 +64,6 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
return self;
}
_callSchemaVersion = TSCallCurrentSchemaVersion;
_callType = callType;
_offerType = offerType;
@ -127,43 +122,9 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
// --- CODE GENERATION MARKER
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:[self valueForKey:@"callSchemaVersion"] forKey:@"callSchemaVersion"];
[coder encodeObject:[self valueForKey:@"callType"] forKey:@"callType"];
[coder encodeObject:[self valueForKey:@"offerType"] forKey:@"offerType"];
[coder encodeObject:[self valueForKey:@"read"] forKey:@"read"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_callSchemaVersion = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"callSchemaVersion"] unsignedIntegerValue];
self->_callType = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"callType"] unsignedIntegerValue];
self->_offerType = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"offerType"] unsignedIntegerValue];
self->_read = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"read"] boolValue];
if (self.callSchemaVersion < 1) {
// Assume user has already seen any call that predate read-tracking
_read = YES;
}
_callSchemaVersion = TSCallCurrentSchemaVersion;
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];
result ^= self.callSchemaVersion;
result ^= self.callType;
result ^= self.offerType;
result ^= self.read;
@ -176,9 +137,6 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
return NO;
}
TSCall *typedOther = (TSCall *)other;
if (self.callSchemaVersion != typedOther.callSchemaVersion) {
return NO;
}
if (self.callType != typedOther.callType) {
return NO;
}
@ -194,7 +152,6 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
- (id)copyWithZone:(nullable NSZone *)zone
{
TSCall *result = [super copyWithZone:zone];
result->_callSchemaVersion = self.callSchemaVersion;
result->_callType = self.callType;
result->_offerType = self.offerType;
result->_read = self.read;

View File

@ -28,6 +28,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -6,7 +6,7 @@
/// Represents a call event that occurred on this device that we want to
/// communicate to our linked devices.
@objc(OutgoingCallEvent)
class OutgoingCallEvent: NSObject, NSCoding {
class OutgoingCallEvent: NSObject, NSSecureCoding {
enum CallType: UInt {
case audio
case video
@ -49,7 +49,7 @@ class OutgoingCallEvent: NSObject, NSCoding {
self.eventType = eventType
}
// MARK: NSCoding
// MARK: NSSecureCoding
private enum Keys {
static let timestamp = "timestamp"
@ -60,6 +60,8 @@ class OutgoingCallEvent: NSObject, NSCoding {
static let eventType = "event"
}
static var supportsSecureCoding: Bool { true }
func encode(with coder: NSCoder) {
coder.encode(NSNumber(value: timestamp), forKey: Keys.timestamp)
coder.encode(conversationId as NSData, forKey: Keys.conversationId)
@ -71,14 +73,14 @@ class OutgoingCallEvent: NSObject, NSCoding {
required init?(coder: NSCoder) {
guard
let timestamp = coder.decodeObject(of: NSNumber.self, forKey: Keys.timestamp) as? UInt64,
let timestamp = coder.decodeObject(of: NSNumber.self, forKey: Keys.timestamp)?.uint64Value,
let conversationId = coder.decodeObject(of: NSData.self, forKey: Keys.conversationId) as Data?,
let callId = coder.decodeObject(of: NSNumber.self, forKey: Keys.callId) as? UInt64,
let callTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.callType) as? UInt,
let callId = coder.decodeObject(of: NSNumber.self, forKey: Keys.callId)?.uint64Value,
let callTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.callType)?.uintValue,
let callType = CallType(rawValue: callTypeRaw),
let eventDirectionRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventDirection) as? UInt,
let eventDirectionRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventDirection)?.uintValue,
let eventDirection = EventDirection(rawValue: eventDirectionRaw),
let eventTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventType) as? UInt,
let eventTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventType)?.uintValue,
let eventType = EventType(rawValue: eventTypeRaw)
else {
owsFailDebug("Missing or unrecognized fields!")
@ -102,6 +104,8 @@ class OutgoingCallEvent: NSObject, NSCoding {
/// - SeeAlso ``IncomingCallEventSyncMessageManager``
@objc(OutgoingCallEventSyncMessage)
public class OutgoingCallEventSyncMessage: OWSOutgoingSyncMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.callEvent = coder.decodeObject(of: OutgoingCallEvent.self, forKey: "event")
super.init(coder: coder)

View File

@ -8,6 +8,8 @@ public import SignalRingRTC
@objc(OutgoingCallLinkUpdateMessage)
public class OutgoingCallLinkUpdateMessage: OWSOutgoingSyncMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.adminPasskey = coder.decodeObject(of: NSData.self, forKey: "adminPasskey") as Data?
self.rootKey = coder.decodeObject(of: NSData.self, forKey: "rootKey") as Data?

View File

@ -9,6 +9,8 @@
/// - SeeAlso ``IncomingCallLogEventSyncMessageManager``
@objc(OutgoingCallLogEventSyncMessage)
public class OutgoingCallLogEventSyncMessage: OWSOutgoingSyncMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.callLogEvent = coder.decodeObject(of: CallLogEvent.self, forKey: "callLogEvent")
super.init(coder: coder)
@ -79,7 +81,7 @@ public class OutgoingCallLogEventSyncMessage: OWSOutgoingSyncMessage {
public extension OutgoingCallLogEventSyncMessage {
@objc(OutgoingCallLogEvent)
class CallLogEvent: NSObject, NSCoding {
class CallLogEvent: NSObject, NSSecureCoding {
public enum EventType: UInt, CaseIterable {
/// Indicates we cleared our call log in its entirety.
///
@ -116,7 +118,7 @@ public extension OutgoingCallLogEventSyncMessage {
self.timestamp = timestamp
}
// MARK: NSCoding
// MARK: NSSecureCoding
private enum Keys {
static let eventType = "eventType"
@ -125,11 +127,13 @@ public extension OutgoingCallLogEventSyncMessage {
static let conversationId = "conversationId"
}
public static var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
guard
let eventTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventType) as? UInt,
let eventTypeRaw = coder.decodeObject(of: NSNumber.self, forKey: Keys.eventType)?.uintValue,
let eventType = EventType(rawValue: eventTypeRaw),
let timestamp = coder.decodeObject(of: NSNumber.self, forKey: Keys.timestamp) as? UInt64
let timestamp = coder.decodeObject(of: NSNumber.self, forKey: Keys.timestamp)?.uint64Value
else {
owsFailDebug("Missing or unrecognized fields!")
return nil
@ -139,7 +143,7 @@ public extension OutgoingCallLogEventSyncMessage {
self.timestamp = timestamp
if
let callId = coder.decodeObject(of: NSNumber.self, forKey: Keys.callId) as? UInt64,
let callId = coder.decodeObject(of: NSNumber.self, forKey: Keys.callId)?.uint64Value,
let conversationId = coder.decodeObject(of: NSData.self, forKey: Keys.conversationId) as Data?
{
self.callId = callId

View File

@ -12,7 +12,7 @@ final class ContactTest: XCTestCase {
func testStableDecoding0() throws {
let encodedValue = try XCTUnwrap(Data(base64Encoded: "YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGvECALDCUmKjA5Ojs8PUFCQ0hJSktQVmhpamtscHR4goOEhVUkbnVsbNwNDg8QERITFBUWFxgZGhscGR4fICEiIyRbY25Db250YWN0SWRfEA9NVExNb2RlbFZlcnNpb25ZZmlyc3ROYW1lWGxhc3ROYW1lWHVuaXF1ZUlkXxAScGhvbmVOdW1iZXJOYW1lTWFwViRjbGFzc18QEnBhcnNlZFBob25lTnVtYmVyc18QFHVzZXJUZXh0UGhvbmVOdW1iZXJzWGZ1bGxOYW1lVmVtYWlsc1huaWNrbmFtZYAQgAKAC4AegBCABYAfgBGADYAdgAOADBAA0icTKClaTlMub2JqZWN0c6CABNIrLC0uWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNBcnJheaItL1hOU09iamVjdNMxJxMyNThXTlMua2V5c6IzNIAGgAeiNjeACIAJgApcKzE3NjM1NTUwMTAxXCsxNzYzNTU1MDEwMFRXb3JrVk1vYmlsZdIrLD4/XE5TRGljdGlvbmFyeaJAL1xOU0RpY3Rpb25hcnlUSm9oblZKb2hubnnSJxNEKaJFRoAOgA+ABF4oNzYzKSA1NTUtMDEwMF4oNzYzKSA1NTUtMDEwMV8QLUNCQTZEMzJDLTVGQkUtNDU4My04QTRDLTQ4QjA1RDVFRTc0NzpBQlBlcnNvbtInE0wpok1OgBKAGoAE01ETUjRUVV8QIVJQRGVmYXVsdHNLZXlQaG9uZU51bWJlckNhbm9uaWNhbF8QHlJQRGVmYXVsdHNLZXlQaG9uZU51bWJlclN0cmluZ4AHgBmAE9kTV1hZWltcXV5fYGFiYGRgZmBfEBFjb3VudHJ5Q29kZVNvdXJjZV8QEml0YWxpYW5MZWFkaW5nWmVyb15uYXRpb25hbE51bWJlcl8QHHByZWZlcnJlZERvbWVzdGljQ2FycmllckNvZGVbY291bnRyeUNvZGVZZXh0ZW5zaW9uXxAUbnVtYmVyT2ZMZWFkaW5nWmVyb3NYcmF3SW5wdXSAGIAAgBaAFYAAgBSAAIAXgAAQARMAAAABxx0/lAgQAdIrLG1uXU5CUGhvbmVOdW1iZXKiby9dTkJQaG9uZU51bWJlctIrLHFyW1Bob25lTnVtYmVyonMvW1Bob25lTnVtYmVy01ETUjNUd4AGgBmAG9kTV1hZWltcXV5fYGF8YGRgZmCAGIAAgBaAHIAAgBSAAIAXgAATAAAAAccdP5VYSm9obiBEb2VTRG9l0isshodXQ29udGFjdKOGiC9YTVRMTW9kZWwACAARABoAJAApADIANwBJAEwAUQBTAHYAfACVAKEAswC9AMYAzwDkAOsBAAEXASABJwEwATIBNAE2ATgBOgE8AT4BQAFCAUQBRgFIAUoBTwFaAVsBXQFiAW0BdgF+AYEBigGRAZkBnAGeAaABowGlAacBqQG2AcMByAHPAdQB4QHkAfEB9gH9AgICBQIHAgkCCwIaAikCWQJeAmECYwJlAmcCbgKSArMCtQK3ArkCzALgAvUDBAMjAy8DOQNQA1kDWwNdA18DYQNjA2UDZwNpA2sDbQN2A3cDeQN+A4wDjwOdA6IDrgOxA70DxAPGA8gDygPdA98D4QPjA+UD5wPpA+sD7QPvA/gEAQQFBAoEEgQWAAAAAAAAAgEAAAAAAAAAiQAAAAAAAAAAAAAAAAAABB8="))
let decodedContact = try NSKeyedUnarchiver.unarchivedObject(ofClass: Contact.self, from: encodedValue, requiringSecureCoding: false)
let decodedContact = try NSKeyedUnarchiver.unarchivedObject(ofClass: Contact.self, from: encodedValue)
XCTAssertEqual(decodedContact?.cnContactId, "CBA6D32C-5FBE-4583-8A4C-48B05D5EE747:ABPerson")
XCTAssertEqual(decodedContact?.firstName, "John")
XCTAssertEqual(decodedContact?.lastName, "Doe")
@ -23,7 +23,7 @@ final class ContactTest: XCTestCase {
func testStableDecoding1() throws {
let encodedValue = try XCTUnwrap(Data(base64Encoded: "YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGoCwwZGhscHR5VJG51bGzWDQ4PEBESExQVFhcYWWZpcnN0TmFtZVhsYXN0TmFtZVhuaWNrbmFtZVhmdWxsTmFtZVtjbkNvbnRhY3RJZFYkY2xhc3OAA4AEgAaABYACgAdfEC1DQkE2RDMyQy01RkJFLTQ1ODMtOEE0Qy00OEIwNUQ1RUU3NDc6QUJQZXJzb25USm9oblNEb2VYSm9obiBEb2VWSm9obm550h8gISJaJGNsYXNzbmFtZVgkY2xhc3Nlc1dDb250YWN0oiEjWE5TT2JqZWN0AAgAEQAaACQAKQAyADcASQBMAFEAUwBcAGIAbwB5AIIAiwCUAKAApwCpAKsArQCvALEAswDjAOgA7AD1APwBAQEMARUBHQEgAAAAAAAAAgEAAAAAAAAAJAAAAAAAAAAAAAAAAAAAASk="))
let decodedContact = try NSKeyedUnarchiver.unarchivedObject(ofClass: Contact.self, from: encodedValue, requiringSecureCoding: false)
let decodedContact = try NSKeyedUnarchiver.unarchivedObject(ofClass: Contact.self, from: encodedValue)
XCTAssertEqual(decodedContact?.cnContactId, "CBA6D32C-5FBE-4583-8A4C-48B05D5EE747:ABPerson")
XCTAssertEqual(decodedContact?.firstName, "John")
XCTAssertEqual(decodedContact?.lastName, "Doe")

View File

@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class DBReadTransaction;
@class TSThread;
@interface OWSDisappearingMessagesConfiguration : BaseModel <NSCoding, NSCopying>
@interface OWSDisappearingMessagesConfiguration : BaseModel <NSSecureCoding, NSCopying>
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

View File

@ -20,6 +20,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSDisappearingMessagesConfiguration
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[self encodeIdsWithCoder:coder];

View File

@ -13,7 +13,9 @@ import Foundation
/// with an attached version that, at time of writing, used by 1:1 conversations (TSContactThread)
/// which are subject to races in setting their DM timer config.
@objc
public final class DisappearingMessageToken: NSObject, NSCoding, NSCopying {
public final class DisappearingMessageToken: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.durationSeconds = coder.decodeObject(of: NSNumber.self, forKey: "durationSeconds")?.uint32Value ?? 0
}

View File

@ -180,7 +180,7 @@ extension TSThread {
let mentionNotificationMode: TSThreadMentionNotificationMode = TSThreadMentionNotificationMode(rawValue: record.mentionNotificationMode) ?? .default
let messageDraft: String? = record.messageDraft
let messageDraftBodyRangesSerialized: Data? = record.messageDraftBodyRanges
let messageDraftBodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(messageDraftBodyRangesSerialized, name: "messageDraftBodyRanges")
let messageDraftBodyRanges: MessageBodyRanges? = try messageDraftBodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) })
let mutedUntilDateObsoleteInterval: Double? = record.mutedUntilDate
let mutedUntilDateObsolete: Date? = SDSDeserialization.optionalDoubleAsDate(mutedUntilDateObsoleteInterval, name: "mutedUntilDateObsolete")
let mutedUntilTimestampObsolete: UInt64 = record.mutedUntilTimestamp
@ -232,14 +232,14 @@ extension TSThread {
let mentionNotificationMode: TSThreadMentionNotificationMode = TSThreadMentionNotificationMode(rawValue: record.mentionNotificationMode) ?? .default
let messageDraft: String? = record.messageDraft
let messageDraftBodyRangesSerialized: Data? = record.messageDraftBodyRanges
let messageDraftBodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(messageDraftBodyRangesSerialized, name: "messageDraftBodyRanges")
let messageDraftBodyRanges: MessageBodyRanges? = try messageDraftBodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) })
let mutedUntilDateObsoleteInterval: Double? = record.mutedUntilDate
let mutedUntilDateObsolete: Date? = SDSDeserialization.optionalDoubleAsDate(mutedUntilDateObsoleteInterval, name: "mutedUntilDateObsolete")
let mutedUntilTimestampObsolete: UInt64 = record.mutedUntilTimestamp
let shouldThreadBeVisible: Bool = record.shouldThreadBeVisible
let storyViewMode: TSThreadStoryViewMode = TSThreadStoryViewMode(rawValue: record.storyViewMode) ?? .default
let groupModelSerialized: Data? = record.groupModel
let groupModel: TSGroupModel = try SDSDeserialization.unarchive(groupModelSerialized, name: "groupModel")
let groupModelSerialized: Data = try record.groupModel ?? { () -> Data in throw SDSError.missingRequiredField(fieldName: "groupModel") }()
let groupModel: TSGroupModel = try SDSDeserialization.unarchivedObject(ofClass: TSGroupModel.self, from: groupModelSerialized)
return TSGroupThread(grdbId: recordId,
uniqueId: uniqueId,
@ -281,7 +281,7 @@ extension TSThread {
let mentionNotificationMode: TSThreadMentionNotificationMode = TSThreadMentionNotificationMode(rawValue: record.mentionNotificationMode) ?? .default
let messageDraft: String? = record.messageDraft
let messageDraftBodyRangesSerialized: Data? = record.messageDraftBodyRanges
let messageDraftBodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(messageDraftBodyRangesSerialized, name: "messageDraftBodyRanges")
let messageDraftBodyRanges: MessageBodyRanges? = try messageDraftBodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) })
let mutedUntilDateObsoleteInterval: Double? = record.mutedUntilDate
let mutedUntilDateObsolete: Date? = SDSDeserialization.optionalDoubleAsDate(mutedUntilDateObsoleteInterval, name: "mutedUntilDateObsolete")
let mutedUntilTimestampObsolete: UInt64 = record.mutedUntilTimestamp
@ -333,7 +333,7 @@ extension TSThread {
let mentionNotificationMode: TSThreadMentionNotificationMode = TSThreadMentionNotificationMode(rawValue: record.mentionNotificationMode) ?? .default
let messageDraft: String? = record.messageDraft
let messageDraftBodyRangesSerialized: Data? = record.messageDraftBodyRanges
let messageDraftBodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(messageDraftBodyRangesSerialized, name: "messageDraftBodyRanges")
let messageDraftBodyRanges: MessageBodyRanges? = try messageDraftBodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) })
let mutedUntilDateObsoleteInterval: Double? = record.mutedUntilDate
let mutedUntilDateObsolete: Date? = SDSDeserialization.optionalDoubleAsDate(mutedUntilDateObsoleteInterval, name: "mutedUntilDateObsolete")
let mutedUntilTimestampObsolete: UInt64 = record.mutedUntilTimestamp

View File

@ -33,7 +33,7 @@ typedef NS_CLOSED_ENUM(NSUInteger, TSThreadStoryViewMode) {
/**
* TSThread is the superclass of TSContactThread, TSGroupThread, and TSPrivateStoryThread
*/
@interface TSThread : BaseModel <NSCoding, NSCopying>
@interface TSThread : BaseModel <NSCopying>
@property (nonatomic) TSThreadStoryViewMode storyViewMode;
@property (nonatomic, nullable) NSNumber *lastSentStoryTimestamp;
@ -79,9 +79,9 @@ typedef NS_CLOSED_ENUM(NSUInteger, TSThreadStoryViewMode) {
@property (nonatomic) TSThreadMentionNotificationMode mentionNotificationMode;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithUniqueId:(NSString *)uniqueId NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
// --- CODE GENERATION MARKER

View File

@ -109,126 +109,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:(double)lastVisibleSortIdOnScreenPer
// --- CODE GENERATION MARKER
- (void)encodeWithCoder:(NSCoder *)coder
{
[self encodeIdsWithCoder:coder];
NSString *conversationColorNameObsolete = self.conversationColorNameObsolete;
if (conversationColorNameObsolete != nil) {
[coder encodeObject:conversationColorNameObsolete forKey:@"conversationColorNameObsolete"];
}
NSDate *creationDate = self.creationDate;
if (creationDate != nil) {
[coder encodeObject:creationDate forKey:@"creationDate"];
}
NSNumber *editTargetTimestamp = self.editTargetTimestamp;
if (editTargetTimestamp != nil) {
[coder encodeObject:editTargetTimestamp forKey:@"editTargetTimestamp"];
}
[coder encodeObject:[self valueForKey:@"isArchivedByLegacyTimestampForSorting"]
forKey:@"isArchivedByLegacyTimestampForSorting"];
[coder encodeObject:[self valueForKey:@"isArchivedObsolete"] forKey:@"isArchivedObsolete"];
[coder encodeObject:[self valueForKey:@"isMarkedUnreadObsolete"] forKey:@"isMarkedUnreadObsolete"];
[coder encodeObject:[self valueForKey:@"lastDraftInteractionRowId"] forKey:@"lastDraftInteractionRowId"];
[coder encodeObject:[self valueForKey:@"lastDraftUpdateTimestamp"] forKey:@"lastDraftUpdateTimestamp"];
[coder encodeObject:[self valueForKey:@"lastInteractionRowId"] forKey:@"lastInteractionRowId"];
NSNumber *lastSentStoryTimestamp = self.lastSentStoryTimestamp;
if (lastSentStoryTimestamp != nil) {
[coder encodeObject:lastSentStoryTimestamp forKey:@"lastSentStoryTimestamp"];
}
[coder encodeObject:[self valueForKey:@"lastVisibleSortIdObsolete"] forKey:@"lastVisibleSortIdObsolete"];
[coder encodeObject:[self valueForKey:@"lastVisibleSortIdOnScreenPercentageObsolete"]
forKey:@"lastVisibleSortIdOnScreenPercentageObsolete"];
[coder encodeObject:[self valueForKey:@"mentionNotificationMode"] forKey:@"mentionNotificationMode"];
NSString *messageDraft = self.messageDraft;
if (messageDraft != nil) {
[coder encodeObject:messageDraft forKey:@"messageDraft"];
}
MessageBodyRanges *messageDraftBodyRanges = self.messageDraftBodyRanges;
if (messageDraftBodyRanges != nil) {
[coder encodeObject:messageDraftBodyRanges forKey:@"messageDraftBodyRanges"];
}
NSDate *mutedUntilDateObsolete = self.mutedUntilDateObsolete;
if (mutedUntilDateObsolete != nil) {
[coder encodeObject:mutedUntilDateObsolete forKey:@"mutedUntilDateObsolete"];
}
[coder encodeObject:[self valueForKey:@"mutedUntilTimestampObsolete"] forKey:@"mutedUntilTimestampObsolete"];
[coder encodeObject:[self valueForKey:@"shouldThreadBeVisible"] forKey:@"shouldThreadBeVisible"];
[coder encodeObject:[self valueForKey:@"storyViewMode"] forKey:@"storyViewMode"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_conversationColorNameObsolete = [coder decodeObjectOfClass:[NSString class]
forKey:@"conversationColorNameObsolete"];
self->_creationDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"creationDate"];
self->_editTargetTimestamp = [coder decodeObjectOfClass:[NSNumber class] forKey:@"editTargetTimestamp"];
self->_isArchivedByLegacyTimestampForSorting =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"isArchivedByLegacyTimestampForSorting"] boolValue];
self->_isArchivedObsolete = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"isArchivedObsolete"] boolValue];
self->_isMarkedUnreadObsolete = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"isMarkedUnreadObsolete"] boolValue];
self->_lastDraftInteractionRowId =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"lastDraftInteractionRowId"] unsignedLongLongValue];
self->_lastDraftUpdateTimestamp =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"lastDraftUpdateTimestamp"] unsignedLongLongValue];
self->_lastInteractionRowId =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"lastInteractionRowId"] unsignedLongLongValue];
self->_lastSentStoryTimestamp = [coder decodeObjectOfClass:[NSNumber class] forKey:@"lastSentStoryTimestamp"];
self->_lastVisibleSortIdObsolete =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"lastVisibleSortIdObsolete"] unsignedLongLongValue];
self->_lastVisibleSortIdOnScreenPercentageObsolete =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"lastVisibleSortIdOnScreenPercentageObsolete"] doubleValue];
self->_mentionNotificationMode =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"mentionNotificationMode"] unsignedIntegerValue];
self->_messageDraft = [coder decodeObjectOfClass:[NSString class] forKey:@"messageDraft"];
self->_messageDraftBodyRanges = [coder decodeObjectOfClass:[MessageBodyRanges class]
forKey:@"messageDraftBodyRanges"];
self->_mutedUntilDateObsolete = [coder decodeObjectOfClass:[NSDate class] forKey:@"mutedUntilDateObsolete"];
self->_mutedUntilTimestampObsolete =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"mutedUntilTimestampObsolete"] unsignedLongLongValue];
self->_shouldThreadBeVisible = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"shouldThreadBeVisible"] boolValue];
self->_storyViewMode = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"storyViewMode"] unsignedIntegerValue];
// renamed `hasEverHadMessage` -> `shouldThreadBeVisible`
if (!_shouldThreadBeVisible) {
NSNumber *_Nullable legacy_hasEverHadMessage = [coder decodeObjectForKey:@"hasEverHadMessage"];
if (legacy_hasEverHadMessage != nil) {
_shouldThreadBeVisible = legacy_hasEverHadMessage.boolValue;
}
}
if (_conversationColorNameObsolete.length == 0) {
_conversationColorNameObsolete = @"Obsolete";
}
NSDate *_Nullable lastMessageDate = [coder decodeObjectOfClass:NSDate.class forKey:@"lastMessageDate"];
NSDate *_Nullable archivalDate = [coder decodeObjectOfClass:NSDate.class forKey:@"archivalDate"];
_isArchivedByLegacyTimestampForSorting = [self.class legacyIsArchivedWithLastMessageDate:lastMessageDate
archivalDate:archivalDate];
if ([coder decodeObjectForKey:@"archivedAsOfMessageSortId"] != nil) {
OWSAssertDebug(!_isArchivedObsolete);
_isArchivedObsolete = YES;
}
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];
@ -388,11 +268,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:(double)lastVisibleSortIdOnScreenPer
return NO;
}
- (NSString *)colorSeed
{
return self.uniqueId;
}
#pragma mark - To be subclassed.
- (NSArray<SignalServiceAddress *> *)recipientAddressesWithSneakyTransaction
@ -434,22 +309,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:(double)lastVisibleSortIdOnScreenPer
transaction:transaction];
}
#pragma mark - Archival
+ (BOOL)legacyIsArchivedWithLastMessageDate:(nullable NSDate *)lastMessageDate
archivalDate:(nullable NSDate *)archivalDate
{
if (!archivalDate) {
return NO;
}
if (!lastMessageDate) {
return YES;
}
return [archivalDate compare:lastMessageDate] != NSOrderedAscending;
}
#pragma mark - Merging
- (void)mergeFrom:(TSThread *)otherThread

View File

@ -18,6 +18,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSBlockedPhoneNumbersMessage
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@class DBReadTransaction;
@class SignalServiceAddress;
@interface OWSLinkedDeviceReadReceipt : NSObject <NSCoding, NSCopying>
@interface OWSLinkedDeviceReadReceipt : NSObject <NSSecureCoding, NSCopying>
@property (nonatomic, readonly) SignalServiceAddress *senderAddress;
@property (nonatomic, readonly, nullable) NSString *messageUniqueId; // Only nil if decoding old values

View File

@ -42,6 +42,11 @@ NSUInteger const OWSLinkedDeviceReadReceiptSchemaVersion = 1;
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:[self valueForKey:@"linkedDeviceReadReceiptSchemaVersion"]
@ -81,7 +86,8 @@ NSUInteger const OWSLinkedDeviceReadReceiptSchemaVersion = 1;
// renamed timestamp -> messageIdTimestamp
if (!_messageIdTimestamp) {
NSNumber *_Nullable legacyTimestamp = (NSNumber *)[coder decodeObjectForKey:@"timestamp"];
NSNumber *_Nullable legacyTimestamp = (NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"timestamp"];
OWSAssertDebug(legacyTimestamp.unsignedLongLongValue > 0);
_messageIdTimestamp = legacyTimestamp.unsignedLongLongValue;
}
@ -95,7 +101,7 @@ NSUInteger const OWSLinkedDeviceReadReceiptSchemaVersion = 1;
}
if (_linkedDeviceReadReceiptSchemaVersion < 1) {
_senderPhoneNumber = [coder decodeObjectForKey:@"senderId"];
_senderPhoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"senderId"];
OWSAssertDebug(_senderPhoneNumber);
}

View File

@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSReceiptsForSenderMessage ()
@property (nonatomic, readonly, nullable) NSSet<NSString *> *messageUniqueIds;
@property (nonatomic, readonly) NSArray<NSNumber *> *messageTimestamps;
@property (nonatomic, readonly) NSSet<NSNumber *> *messageTimestamps;
@property (nonatomic, readonly) SSKProtoReceiptMessageType receiptType;
@end
@ -72,10 +72,15 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSArray *messageTimestamps = self.messageTimestamps;
NSSet *messageTimestamps = self.messageTimestamps;
if (messageTimestamps != nil) {
[coder encodeObject:messageTimestamps forKey:@"messageTimestamps"];
}
@ -92,7 +97,7 @@ NS_ASSUME_NONNULL_BEGIN
if (!self) {
return self;
}
self->_messageTimestamps = [coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], [NSNumber class] ]]
self->_messageTimestamps = [coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSSet class], [NSNumber class] ]]
forKey:@"messageTimestamps"];
self->_messageUniqueIds = [coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSSet class], [NSString class] ]]
forKey:@"messageUniqueIds"];

View File

@ -19,6 +19,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSStickerPackSyncMessage
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -50,6 +50,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
@ -80,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN
forKey:@"verificationState"] unsignedLongLongValue];
if (_verificationForRecipientAddress == nil) {
NSString *phoneNumber = [coder decodeObjectForKey:@"verificationForRecipientId"];
NSString *phoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"verificationForRecipientId"];
_verificationForRecipientAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil
phoneNumber:phoneNumber];
OWSAssertDebug(_verificationForRecipientAddress.isValid);

View File

@ -35,6 +35,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
@ -64,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
self->_senderAddress = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"senderAddress"];
if (_senderAddress == nil) {
NSString *phoneNumber = [coder decodeObjectForKey:@"senderId"];
NSString *phoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"senderId"];
_senderAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
OWSAssertDebug(_senderAddress.isValid);
}

View File

@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
@class DBReadTransaction;
@class SignalServiceAddress;
@interface OWSLinkedDeviceViewedReceipt : NSObject <NSCoding, NSCopying>
@interface OWSLinkedDeviceViewedReceipt : NSObject <NSSecureCoding, NSCopying>
@property (nonatomic, readonly) SignalServiceAddress *senderAddress;
@property (nonatomic, readonly, nullable) NSString *messageUniqueId; // Only nil if decoding old values

View File

@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
@ -156,6 +161,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:[self valueForKey:@"messageIdTimestamp"] forKey:@"messageIdTimestamp"];

View File

@ -7,6 +7,8 @@
/// should refresh their list of linked devices.
@objc(OutgoingDeviceNameChangeSyncMessage)
public class OutgoingDeviceNameChangeSyncMessage: OWSOutgoingSyncMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.deviceId = coder.decodeObject(of: NSNumber.self, forKey: "deviceId")
super.init(coder: coder)

View File

@ -65,7 +65,9 @@ public enum GroupV2Access: UInt, Codable, CustomStringConvertible {
// This class is immutable.
@objc
public final class GroupAccess: NSObject, NSCoding, NSCopying {
public final class GroupAccess: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.addFromInviteLink = (coder.decodeObject(of: NSNumber.self, forKey: "addFromInviteLink")?.uintValue).flatMap(GroupV2Access.init(rawValue:)) ?? .unknown
self.attributes = (coder.decodeObject(of: NSNumber.self, forKey: "attributes")?.uintValue).flatMap(GroupV2Access.init(rawValue:)) ?? .unknown

View File

@ -130,7 +130,7 @@ private enum GroupMemberState: Equatable, Codable, CustomStringConvertible {
// MARK: -
@objc
public class GroupMembership: NSObject, NSCoding {
public class GroupMembership: NSObject, NSSecureCoding {
// MARK: Types
@ -161,16 +161,17 @@ public class GroupMembership: NSObject, NSCoding {
super.init()
}
@objc
public required init?(coder aDecoder: NSCoder) {
if let invalidInviteMap = aDecoder.decodeObject(forKey: Self.invalidInviteMapKey) as? InvalidInviteMap {
self.invalidInviteMap = invalidInviteMap
} else {
// invalidInviteMap is optional.
self.invalidInviteMap = [:]
}
public static var supportsSecureCoding: Bool { true }
if let memberStatesData = aDecoder.decodeObject(forKey: Self.memberStatesKey) as? Data {
@objc
public required init?(coder: NSCoder) {
self.invalidInviteMap = coder.decodeDictionary(
withKeyClass: NSData.self,
objectClass: InvalidInviteModel.self,
forKey: Self.invalidInviteMapKey,
) as [Data: InvalidInviteModel]? ?? [:]
if let memberStatesData = coder.decodeObject(of: NSData.self, forKey: Self.memberStatesKey) as Data? {
let decoder = JSONDecoder()
do {
self.memberStates = try decoder.decode(MemberStateMap.self, from: memberStatesData)
@ -178,14 +179,26 @@ public class GroupMembership: NSObject, NSCoding {
owsFailDebug("Could not decode member states: \(error)")
return nil
}
} else if let legacyMemberStateMap = aDecoder.decodeObject(forKey: Self.legacyMemberStatesKey) as? LegacyMemberStateMap {
} else if
let legacyMemberStateMap = coder.decodeDictionary(
withKeyClass: SignalServiceAddress.self,
objectClass: LegacyMemberState.self,
forKey: Self.legacyMemberStatesKey,
) as LegacyMemberStateMap?
{
self.memberStates = Self.convertLegacyMemberStateMap(legacyMemberStateMap)
} else {
owsFailDebug("Could not decode legacy member states.")
return nil
}
if let bannedMembers = aDecoder.decodeObject(forKey: Self.bannedMembersKey) as? [UUID: BannedAtTimestampMillis] {
if
let bannedMembers = coder.decodeDictionary(
withKeyClass: NSUUID.self,
objectClass: NSNumber.self,
forKey: Self.bannedMembersKey,
) as [UUID: NSNumber]? as? [UUID: UInt64]
{
self.bannedMembers = bannedMembers.mapKeys(injectiveTransform: { Aci(fromUUID: $0) })
} else {
// TODO: (Group Abuse) we should debug assert here eventually.
@ -871,7 +884,9 @@ public class GroupMembership: NSObject, NSCoding {
// MARK: - InvalidInviteModel
@objc(GroupMembershipInvalidInviteModel)
private final class InvalidInviteModel: NSObject, NSCoding, NSCopying {
private final class InvalidInviteModel: NSObject, NSSecureCoding, NSCopying {
static var supportsSecureCoding: Bool { true }
init?(coder: NSCoder) {
self.addedByUserId = coder.decodeObject(of: NSData.self, forKey: "addedByUserId") as Data?
self.userId = coder.decodeObject(of: NSData.self, forKey: "userId") as Data?
@ -917,7 +932,9 @@ private final class InvalidInviteModel: NSObject, NSCoding, NSCopying {
// MARK: - LegacyMemberState
@objc(_TtCC16SignalServiceKit15GroupMembership11MemberState)
private final class LegacyMemberState: NSObject, NSCoding, NSCopying {
private final class LegacyMemberState: NSObject, NSSecureCoding, NSCopying {
static var supportsSecureCoding: Bool { true }
init?(coder: NSCoder) {
self.addedByUuid = coder.decodeObject(of: NSUUID.self, forKey: "addedByUuid") as UUID?
self.isPending = coder.decodeObject(of: NSNumber.self, forKey: "isPending")?.boolValue ?? false

View File

@ -25,7 +25,7 @@ typedef NS_CLOSED_ENUM(uint32_t, GroupsVersion) {
// If you modify this class - especially if you
// add any new properties - make sure to update
// TSGroupModelBuilder.
@interface TSGroupModel : NSObject <NSCoding, NSCopying>
@interface TSGroupModel : NSObject <NSSecureCoding, NSCopying>
// groupMembers includes administrators and normal members.
@property (nonatomic, readonly) NSArray<SignalServiceAddress *> *groupMembers;

View File

@ -72,6 +72,11 @@ NSUInteger const TSGroupModelSchemaVersion = 2;
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
SignalServiceAddress *addedByAddress = self.addedByAddress;
@ -124,7 +129,9 @@ NSUInteger const TSGroupModelSchemaVersion = 2;
OWSAssertDebug([GroupManager isValidGroupId:self.groupId groupsVersion:self.groupsVersion]);
if (_groupModelSchemaVersion < 1) {
NSArray<NSString *> *_Nullable memberE164s = [coder decodeObjectForKey:@"groupMemberIds"];
NSArray<NSString *> *_Nullable memberE164s =
[coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], [NSString class] ]]
forKey:@"groupMemberIds"];
if (memberE164s) {
NSMutableArray<SignalServiceAddress *> *memberAddresses = [NSMutableArray new];
for (NSString *phoneNumber in memberE164s) {
@ -138,7 +145,7 @@ NSUInteger const TSGroupModelSchemaVersion = 2;
}
if (_groupModelSchemaVersion < 2) {
_legacyAvatarData = [coder decodeObjectForKey:@"groupAvatarData"];
_legacyAvatarData = [coder decodeObjectOfClass:[NSData class] forKey:@"groupAvatarData"];
}
_groupModelSchemaVersion = TSGroupModelSchemaVersion;

View File

@ -9,6 +9,8 @@ public import LibSignalClient
@objc
public final class TSGroupModelV2: TSGroupModel {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.access = coder.decodeObject(of: GroupAccess.self, forKey: "access") ?? .defaultForV2
self.avatarDataFailedToFetchFromCDN = coder.decodeObject(of: NSNumber.self, forKey: "avatarDataFailedToFetchFromCDN")?.boolValue ?? false

View File

@ -185,11 +185,7 @@ public final class MessageSenderJobRecord: JobRecord, FactoryInitializableFromRe
forKey: .transientMessage,
).flatMap { invisibleMessageData -> TSOutgoingMessage? in
do {
let result = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(invisibleMessageData) as? TSOutgoingMessage
guard let result else {
throw SDSError.invalidValue()
}
return result
return try LegacySDSSerializer().deserializeLegacySDSData(invisibleMessageData, ofClass: TSOutgoingMessage.self)
} catch {
owsFailDebug("couldn't decode transient message: \(error)")
return nil
@ -211,7 +207,7 @@ public final class MessageSenderJobRecord: JobRecord, FactoryInitializableFromRe
try container.encodeIfPresent(threadId, forKey: .threadId)
try container.encode(useMediaQueue, forKey: .useMediaQueue)
try container.encodeIfPresent(
transientMessage.map { try! NSKeyedArchiver.archivedData(withRootObject: $0, requiringSecureCoding: false) },
transientMessage.map { LegacySDSSerializer().serializeAsLegacySDSData($0) },
forKey: .transientMessage,
)
try container.encode(removeMessageAfterSending, forKey: .removeMessageAfterSending)

View File

@ -12,11 +12,11 @@ public import LibSignalClient
///
/// This object must be further applied to NSAttributedString to actually display mentions and styles.
@objc
public class MessageBodyRanges: NSObject, NSCopying, NSSecureCoding {
public final class MessageBodyRanges: NSObject, NSCopying, NSSecureCoding {
// Limit to up to 250 ranges per message.
public static let maxRangesPerMessage = 250
public static var supportsSecureCoding = true
public static var supportsSecureCoding: Bool { true }
public static var empty: MessageBodyRanges { MessageBodyRanges(mentions: [:], styles: []) }
// Styles are kept separate from mentions; mentions are not allowed to overlap,

View File

@ -11,6 +11,8 @@ import LibSignalClient
/// - SeeAlso ``DeleteForMeOutgoingSyncMessageManager``
@objc(DeleteForMeOutgoingSyncMessage)
class DeleteForMeOutgoingSyncMessage: OWSOutgoingSyncMessage {
override class var supportsSecureCoding: Bool { true }
required init?(coder: NSCoder) {
self.contents = coder.decodeObject(of: NSData.self, forKey: "contents") as Data?
super.init(coder: coder)

View File

@ -69,41 +69,12 @@ NS_ASSUME_NONNULL_BEGIN
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:[self valueForKey:@"isRecipientUpdate"] forKey:@"isRecipientUpdate"];
TSOutgoingMessage *message = self.message;
if (message != nil) {
[coder encodeObject:message forKey:@"message"];
}
TSThread *messageThread = self.messageThread;
if (messageThread != nil) {
[coder encodeObject:messageThread forKey:@"messageThread"];
}
SignalServiceAddress *sentRecipientAddress = self.sentRecipientAddress;
if (sentRecipientAddress != nil) {
[coder encodeObject:sentRecipientAddress forKey:@"sentRecipientAddress"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_isRecipientUpdate = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"isRecipientUpdate"] boolValue];
self->_message = [coder decodeObjectOfClass:[TSOutgoingMessage class] forKey:@"message"];
self->_messageThread = [coder decodeObjectOfClass:[TSThread class] forKey:@"messageThread"];
self->_sentRecipientAddress = [coder decodeObjectOfClass:[SignalServiceAddress class]
forKey:@"sentRecipientAddress"];
if (_sentRecipientAddress == nil) {
NSString *phoneNumber = [coder decodeObjectForKey:@"sentRecipientId"];
_sentRecipientAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
OWSAssertDebug(_sentRecipientAddress.isValid);
}
return self;
return nil;
}
- (NSUInteger)hash

View File

@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSOutgoingSyncMessage
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
return [super initWithCoder:coder];

View File

@ -42,6 +42,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -28,6 +28,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -36,6 +36,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -25,6 +25,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSSyncMessageRequestResponseMessage
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -35,6 +35,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@class AciObjC;
@interface OutgoingPaymentMobileCoin : NSObject <NSCoding, NSCopying>
@interface OutgoingPaymentMobileCoin : NSObject <NSSecureCoding, NSCopying>
@property (nonatomic, readonly, nullable) AciObjC *recipientAci;
@property (nonatomic, readonly, nullable) NSData *recipientAddress;

View File

@ -46,6 +46,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:[self valueForKey:@"amountPicoMob"] forKey:@"amountPicoMob"];
@ -215,6 +220,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -8,6 +8,8 @@ import Foundation
// This needs to reflect the edit as represented (and sourced) from the db.
@objc
public final class OutgoingEditMessage: TSOutgoingMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.editedMessage = coder.decodeObject(of: TSOutgoingMessage.self, forKey: "editedMessage")
self.targetMessageTimestamp = coder.decodeObject(of: NSNumber.self, forKey: "targetMessageTimestamp")?.uint64Value ?? 0

View File

@ -13,12 +13,14 @@ public protocol OWSContactField: AnyObject {
// MARK: - OWSContact
@objc(OWSContact)
public final class OWSContact: NSObject, NSCoding, NSCopying {
public final class OWSContact: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.addresses = coder.decodeObject(of: [NSArray.self, OWSContactAddress.self], forKey: "addresses") as? [OWSContactAddress] ?? []
self.emails = coder.decodeObject(of: [NSArray.self, OWSContactEmail.self], forKey: "emails") as? [OWSContactEmail] ?? []
self.addresses = coder.decodeArrayOfObjects(ofClass: OWSContactAddress.self, forKey: "addresses") ?? []
self.emails = coder.decodeArrayOfObjects(ofClass: OWSContactEmail.self, forKey: "emails") ?? []
self.name = coder.decodeObject(of: OWSContactName.self, forKey: "name") ?? OWSContactName()
self.phoneNumbers = coder.decodeObject(of: [NSArray.self, OWSContactPhoneNumber.self], forKey: "phoneNumbers") as? [OWSContactPhoneNumber] ?? []
self.phoneNumbers = coder.decodeArrayOfObjects(ofClass: OWSContactPhoneNumber.self, forKey: "phoneNumbers") ?? []
}
public func encode(with coder: NSCoder) {

View File

@ -6,7 +6,9 @@
public import Contacts
@objc(OWSContactAddress)
public final class OWSContactAddress: NSObject, NSCoding, NSCopying, OWSContactField {
public final class OWSContactAddress: NSObject, NSSecureCoding, NSCopying, OWSContactField {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.type = (coder.decodeObject(of: NSNumber.self, forKey: "addressType")?.intValue).flatMap(`Type`.init(rawValue:)) ?? .home
self.city = coder.decodeObject(of: NSString.self, forKey: "city") as String?

View File

@ -6,7 +6,9 @@
public import Contacts
@objc(OWSContactEmail)
public final class OWSContactEmail: NSObject, NSCoding, NSCopying, OWSContactField {
public final class OWSContactEmail: NSObject, NSSecureCoding, NSCopying, OWSContactField {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.email = coder.decodeObject(of: NSString.self, forKey: "email") as String? ?? ""
self.type = (coder.decodeObject(of: NSNumber.self, forKey: "emailType")?.intValue).flatMap(`Type`.init(rawValue:)) ?? .home

View File

@ -6,7 +6,9 @@
public import Contacts
@objc(OWSContactName)
public final class OWSContactName: NSObject, NSCoding, NSCopying {
public final class OWSContactName: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.familyName = coder.decodeObject(of: NSString.self, forKey: "familyName") as String?
self.givenName = coder.decodeObject(of: NSString.self, forKey: "givenName") as String?

View File

@ -6,7 +6,9 @@
public import Contacts
@objc(OWSContactPhoneNumber)
public final class OWSContactPhoneNumber: NSObject, NSCoding, NSCopying, OWSContactField {
public final class OWSContactPhoneNumber: NSObject, NSSecureCoding, NSCopying, OWSContactField {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.label = coder.decodeObject(of: NSString.self, forKey: "label") as String?
self.phoneNumber = coder.decodeObject(of: NSString.self, forKey: "phoneNumber") as String? ?? ""

View File

@ -67,7 +67,9 @@ public class OWSLinkPreviewDraft: Equatable {
// MARK: - OWSLinkPreview
@objc
public final class OWSLinkPreview: NSObject, NSCoding, NSCopying, Codable {
public final class OWSLinkPreview: NSObject, NSSecureCoding, NSCopying, Codable {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.date = coder.decodeObject(of: NSDate.self, forKey: "date") as Date?
self.previewDescription = coder.decodeObject(of: NSString.self, forKey: "previewDescription") as String?

View File

@ -64,8 +64,6 @@ NS_ASSUME_NONNULL_BEGIN
serverGuid:(nullable NSString *)serverGuid
unregisteredAddress:(nullable SignalServiceAddress *)unregisteredAddress NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
/// Create a new disappearing-timer-update info message.
///
/// - Parameter timestamp

View File

@ -24,35 +24,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSDisappearingConfigurationUpdateInfoMessage
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:[self valueForKey:@"configurationDurationSeconds"] forKey:@"configurationDurationSeconds"];
[coder encodeObject:[self valueForKey:@"configurationIsEnabled"] forKey:@"configurationIsEnabled"];
NSString *createdByRemoteName = self.createdByRemoteName;
if (createdByRemoteName != nil) {
[coder encodeObject:createdByRemoteName forKey:@"createdByRemoteName"];
}
[coder encodeObject:[self valueForKey:@"createdInExistingGroup"] forKey:@"createdInExistingGroup"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_configurationDurationSeconds =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"configurationDurationSeconds"] unsignedIntValue];
self->_configurationIsEnabled = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"configurationIsEnabled"] boolValue];
self->_createdByRemoteName = [coder decodeObjectOfClass:[NSString class] forKey:@"createdByRemoteName"];
self->_createdInExistingGroup = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"createdInExistingGroup"] boolValue];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];

View File

@ -48,6 +48,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSEndSessionMessage
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
return [super initWithCoder:coder];

View File

@ -20,7 +20,9 @@ public enum OWSGiftBadgeRedemptionState: Int {
}
@objc
public final class OWSGiftBadge: NSObject, NSCoding, NSCopying {
public final class OWSGiftBadge: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.redemptionCredential = coder.decodeObject(of: NSData.self, forKey: "redemptionCredential") as Data?
self.redemptionState = (coder.decodeObject(of: NSNumber.self, forKey: "redemptionState")?.intValue).flatMap(OWSGiftBadgeRedemptionState.init(rawValue:)) ?? .pending

View File

@ -38,6 +38,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -76,8 +76,6 @@ NS_ASSUME_NONNULL_BEGIN
verificationState:(OWSVerificationState)verificationState
isLocalChange:(BOOL)isLocalChange NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
// --- CODE GENERATION MARKER
// This snippet is generated by /Scripts/sds_codegen/sds_generate.py. Do not manually edit it, instead run

View File

@ -37,35 +37,6 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:[self valueForKey:@"isLocalChange"] forKey:@"isLocalChange"];
SignalServiceAddress *recipientAddress = self.recipientAddress;
if (recipientAddress != nil) {
[coder encodeObject:recipientAddress forKey:@"recipientAddress"];
}
[coder encodeObject:[self valueForKey:@"verificationState"] forKey:@"verificationState"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_isLocalChange = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"isLocalChange"] boolValue];
self->_recipientAddress = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"recipientAddress"];
self->_verificationState = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"verificationState"] unsignedLongLongValue];
if (_recipientAddress == nil) {
NSString *_Nullable phoneNumber = [coder decodeObjectForKey:@"recipientId"];
_recipientAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
OWSAssertDebug(_recipientAddress.isValid);
}
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];

View File

@ -7,6 +7,8 @@ import Foundation
public import LibSignalClient
public class OutgoingPinMessage: TSOutgoingMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.pinDurationForever = coder.decodeObject(of: NSNumber.self, forKey: "pinDurationForever")?.boolValue ?? false
self.pinDurationSeconds = coder.decodeObject(of: NSNumber.self, forKey: "pinDurationSeconds")?.uint32Value ?? 0

View File

@ -7,6 +7,8 @@ import Foundation
public import LibSignalClient
public class OutgoingUnpinMessage: TSOutgoingMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.targetMessageAuthorAciBinary = coder.decodeObject(of: NSData.self, forKey: "targetMessageAuthorAciBinary") as Data?
self.targetMessageTimestamp = coder.decodeObject(of: NSNumber.self, forKey: "targetMessageTimestamp")?.uint64Value ?? 0

View File

@ -6,6 +6,8 @@
import Foundation
class OutgoingPollTerminateMessage: TSOutgoingMessage {
override class var supportsSecureCoding: Bool { true }
required init?(coder: NSCoder) {
self.targetPollTimestamp = coder.decodeObject(of: NSNumber.self, forKey: "targetPollTimestamp")?.uint64Value ?? 0
super.init(coder: coder)

View File

@ -7,11 +7,13 @@ import Foundation
public import LibSignalClient
public class OutgoingPollVoteMessage: TSOutgoingMessage {
override public class var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
self.targetPollAuthorAciBinary = coder.decodeObject(of: NSData.self, forKey: "targetPollAuthorAciBinary") as Data?
self.targetPollTimestamp = coder.decodeObject(of: NSNumber.self, forKey: "targetPollTimestamp")?.uint64Value ?? 0
self.voteCount = coder.decodeObject(of: NSNumber.self, forKey: "voteCount")?.uint32Value ?? 0
self.voteOptionIndexes = coder.decodeObject(of: [NSArray.self, NSNumber.self], forKey: "voteOptionIndexes") as? [UInt32] ?? []
self.voteOptionIndexes = coder.decodeArrayOfObjects(ofClass: NSNumber.self, forKey: "voteOptionIndexes").map({ $0.map(\.uint32Value) })
super.init(coder: coder)
}

View File

@ -30,9 +30,8 @@ typedef NS_ENUM(NSUInteger, TSQuotedMessageContentSource) {
TSQuotedMessageContentSourceStory
};
@interface OWSAttachmentInfo : NSObject <NSCoding, NSCopying>
@interface OWSAttachmentInfo : NSObject <NSSecureCoding, NSCopying>
@property (class, nonatomic, readonly) NSUInteger currentSchemaVersion;
@property (nonatomic, readonly) NSUInteger schemaVersion;
@property (nonatomic, readonly, nullable) NSString *attachmentId;
@ -77,7 +76,7 @@ typedef NS_ENUM(NSUInteger, TSQuotedMessageContentSource) {
@end
@interface TSQuotedMessage : NSObject <NSCoding, NSCopying>
@interface TSQuotedMessage : NSObject <NSSecureCoding, NSCopying>
@property (nullable, nonatomic, readonly) NSNumber *timestampValue;
@property (nonatomic, readonly) SignalServiceAddress *authorAddress;

View File

@ -42,7 +42,6 @@ NS_ASSUME_NONNULL_BEGIN
{
self = [super init];
if (self) {
_schemaVersion = self.class.currentSchemaVersion;
_contentType = originalAttachmentMimeType;
_sourceFilename = originalAttachmentSourceFilename;
}
@ -60,6 +59,11 @@ NS_ASSUME_NONNULL_BEGIN
// MARK: -
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
NSString *attachmentId = self.attachmentId;
@ -70,7 +74,6 @@ NS_ASSUME_NONNULL_BEGIN
if (contentType != nil) {
[coder encodeObject:contentType forKey:@"contentType"];
}
[coder encodeObject:[self valueForKey:@"schemaVersion"] forKey:@"schemaVersion"];
NSString *sourceFilename = self.sourceFilename;
if (sourceFilename != nil) {
[coder encodeObject:sourceFilename forKey:@"sourceFilename"];
@ -85,10 +88,7 @@ NS_ASSUME_NONNULL_BEGIN
}
self->_attachmentId = [coder decodeObjectOfClass:[NSString class] forKey:@"attachmentId"];
self->_contentType = [coder decodeObjectOfClass:[NSString class] forKey:@"contentType"];
self->_schemaVersion = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"schemaVersion"] unsignedIntegerValue];
self->_sourceFilename = [coder decodeObjectOfClass:[NSString class] forKey:@"sourceFilename"];
_schemaVersion = self.class.currentSchemaVersion;
return self;
}
@ -97,7 +97,6 @@ NS_ASSUME_NONNULL_BEGIN
NSUInteger result = 0;
result ^= self.attachmentId.hash;
result ^= self.contentType.hash;
result ^= self.schemaVersion;
result ^= self.sourceFilename.hash;
return result;
}
@ -114,9 +113,6 @@ NS_ASSUME_NONNULL_BEGIN
if (![NSObject isObject:self.contentType equalToObject:typedOther.contentType]) {
return NO;
}
if (self.schemaVersion != typedOther.schemaVersion) {
return NO;
}
if (![NSObject isObject:self.sourceFilename equalToObject:typedOther.sourceFilename]) {
return NO;
}
@ -128,7 +124,6 @@ NS_ASSUME_NONNULL_BEGIN
OWSAttachmentInfo *result = [[[self class] allocWithZone:zone] init];
result->_attachmentId = self.attachmentId;
result->_contentType = self.contentType;
result->_schemaVersion = self.schemaVersion;
result->_sourceFilename = self.sourceFilename;
return result;
}
@ -205,6 +200,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
SignalServiceAddress *authorAddress = self.authorAddress;
@ -250,7 +250,7 @@ NS_ASSUME_NONNULL_BEGIN
forKey:@"timestamp"] unsignedLongLongValue];
if (_authorAddress == nil) {
NSString *phoneNumber = [coder decodeObjectForKey:@"authorId"];
NSString *phoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"authorId"];
_authorAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
OWSAssertDebug(_authorAddress.isValid);
}

View File

@ -90,7 +90,7 @@ extern NSUInteger TSErrorMessageSchemaVersion;
- (instancetype)initErrorMessageWithBuilder:(TSErrorMessageBuilder *)errorMessageBuilder NS_DESIGNATED_INITIALIZER
NS_SWIFT_NAME(init(errorMessageWithBuilder:));
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
// --- CODE GENERATION MARKER

View File

@ -9,80 +9,21 @@
NS_ASSUME_NONNULL_BEGIN
NSUInteger TSErrorMessageSchemaVersion = 2;
#pragma mark -
@interface TSErrorMessage ()
@property (nonatomic, getter=wasRead) BOOL read;
@property (nonatomic, readonly) NSUInteger errorMessageSchemaVersion;
@end
#pragma mark -
@implementation TSErrorMessage
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:[self valueForKey:@"errorMessageSchemaVersion"] forKey:@"errorMessageSchemaVersion"];
[coder encodeObject:[self valueForKey:@"errorType"] forKey:@"errorType"];
[coder encodeObject:[self valueForKey:@"read"] forKey:@"read"];
SignalServiceAddress *recipientAddress = self.recipientAddress;
if (recipientAddress != nil) {
[coder encodeObject:recipientAddress forKey:@"recipientAddress"];
}
SignalServiceAddress *sender = self.sender;
if (sender != nil) {
[coder encodeObject:sender forKey:@"sender"];
}
[coder encodeObject:[self valueForKey:@"wasIdentityVerified"] forKey:@"wasIdentityVerified"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_errorMessageSchemaVersion =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"errorMessageSchemaVersion"] unsignedIntegerValue];
self->_errorType = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"errorType"] intValue];
self->_read = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"read"] boolValue];
self->_recipientAddress = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"recipientAddress"];
self->_sender = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"sender"];
self->_wasIdentityVerified = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"wasIdentityVerified"] boolValue];
if (self.errorMessageSchemaVersion < 1) {
_read = YES;
}
if (self.errorMessageSchemaVersion == 1) {
NSString *_Nullable phoneNumber = [coder decodeObjectForKey:@"recipientId"];
if (phoneNumber) {
_recipientAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
OWSAssertDebug(_recipientAddress.isValid);
}
}
_errorMessageSchemaVersion = TSErrorMessageSchemaVersion;
if (self.isDynamicInteraction) {
self.read = YES;
}
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];
result ^= self.errorMessageSchemaVersion;
result ^= (NSUInteger)self.errorType;
result ^= self.read;
result ^= self.recipientAddress.hash;
@ -97,9 +38,6 @@ NSUInteger TSErrorMessageSchemaVersion = 2;
return NO;
}
TSErrorMessage *typedOther = (TSErrorMessage *)other;
if (self.errorMessageSchemaVersion != typedOther.errorMessageSchemaVersion) {
return NO;
}
if (self.errorType != typedOther.errorType) {
return NO;
}
@ -121,7 +59,6 @@ NSUInteger TSErrorMessageSchemaVersion = 2;
- (id)copyWithZone:(nullable NSZone *)zone
{
TSErrorMessage *result = [super copyWithZone:zone];
result->_errorMessageSchemaVersion = self.errorMessageSchemaVersion;
result->_errorType = self.errorType;
result->_read = self.read;
result->_recipientAddress = self.recipientAddress;
@ -141,7 +78,6 @@ NSUInteger TSErrorMessageSchemaVersion = 2;
_errorType = errorMessageBuilder.errorType;
_sender = errorMessageBuilder.senderAddress;
_recipientAddress = errorMessageBuilder.recipientAddress;
_errorMessageSchemaVersion = TSErrorMessageSchemaVersion;
_wasIdentityVerified = errorMessageBuilder.wasIdentityVerified;
if (self.isDynamicInteraction) {

View File

@ -64,7 +64,7 @@ NS_ASSUME_NONNULL_BEGIN
storyTimestamp:(nullable NSNumber *)storyTimestamp
wasRemotelyDeleted:(BOOL)wasRemotelyDeleted NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
- (instancetype)initIncomingMessageWithBuilder:(TSIncomingMessageBuilder *)incomingMessageBuilder
NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(incomingMessageWithBuilder:));

View File

@ -17,91 +17,19 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, getter=wasViewed) BOOL viewed;
@property (nonatomic, nullable) NSNumber *serverTimestamp;
@property (nonatomic, readonly) NSUInteger incomingMessageSchemaVersion;
@end
#pragma mark -
const NSUInteger TSIncomingMessageSchemaVersion = 1;
@implementation TSIncomingMessage
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSString *authorPhoneNumber = self.authorPhoneNumber;
if (authorPhoneNumber != nil) {
[coder encodeObject:authorPhoneNumber forKey:@"authorPhoneNumber"];
}
NSString *authorUUID = self.authorUUID;
if (authorUUID != nil) {
[coder encodeObject:authorUUID forKey:@"authorUUID"];
}
NSNumber *deprecated_sourceDeviceId = self.deprecated_sourceDeviceId;
if (deprecated_sourceDeviceId != nil) {
[coder encodeObject:deprecated_sourceDeviceId forKey:@"deprecated_sourceDeviceId"];
}
[coder encodeObject:[self valueForKey:@"incomingMessageSchemaVersion"] forKey:@"incomingMessageSchemaVersion"];
[coder encodeObject:[self valueForKey:@"read"] forKey:@"read"];
[coder encodeObject:[self valueForKey:@"serverDeliveryTimestamp"] forKey:@"serverDeliveryTimestamp"];
NSString *serverGuid = self.serverGuid;
if (serverGuid != nil) {
[coder encodeObject:serverGuid forKey:@"serverGuid"];
}
NSNumber *serverTimestamp = self.serverTimestamp;
if (serverTimestamp != nil) {
[coder encodeObject:serverTimestamp forKey:@"serverTimestamp"];
}
[coder encodeObject:[self valueForKey:@"viewed"] forKey:@"viewed"];
[coder encodeObject:[self valueForKey:@"wasReceivedByUD"] forKey:@"wasReceivedByUD"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_authorPhoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"authorPhoneNumber"];
self->_authorUUID = [coder decodeObjectOfClass:[NSString class] forKey:@"authorUUID"];
self->_deprecated_sourceDeviceId = [coder decodeObjectOfClass:[NSNumber class] forKey:@"deprecated_sourceDeviceId"];
self->_incomingMessageSchemaVersion =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"incomingMessageSchemaVersion"] unsignedIntegerValue];
self->_read = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"read"] boolValue];
self->_serverDeliveryTimestamp =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"serverDeliveryTimestamp"] unsignedLongLongValue];
self->_serverGuid = [coder decodeObjectOfClass:[NSString class] forKey:@"serverGuid"];
self->_serverTimestamp = [coder decodeObjectOfClass:[NSNumber class] forKey:@"serverTimestamp"];
self->_viewed = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"viewed"] boolValue];
self->_wasReceivedByUD = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"wasReceivedByUD"] boolValue];
if (_incomingMessageSchemaVersion < 1) {
_authorPhoneNumber = [coder decodeObjectForKey:@"authorId"];
if (_authorPhoneNumber == nil) {
_authorPhoneNumber = [TSContactThread legacyContactPhoneNumberFromThreadId:self.uniqueThreadId];
}
}
if (_authorUUID != nil) {
_authorPhoneNumber = nil;
}
_incomingMessageSchemaVersion = TSIncomingMessageSchemaVersion;
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];
result ^= self.authorPhoneNumber.hash;
result ^= self.authorUUID.hash;
result ^= self.deprecated_sourceDeviceId.hash;
result ^= self.incomingMessageSchemaVersion;
result ^= self.read;
result ^= self.serverDeliveryTimestamp;
result ^= self.serverGuid.hash;
@ -126,9 +54,6 @@ const NSUInteger TSIncomingMessageSchemaVersion = 1;
if (![NSObject isObject:self.deprecated_sourceDeviceId equalToObject:typedOther.deprecated_sourceDeviceId]) {
return NO;
}
if (self.incomingMessageSchemaVersion != typedOther.incomingMessageSchemaVersion) {
return NO;
}
if (self.read != typedOther.read) {
return NO;
}
@ -156,7 +81,6 @@ const NSUInteger TSIncomingMessageSchemaVersion = 1;
result->_authorPhoneNumber = self.authorPhoneNumber;
result->_authorUUID = self.authorUUID;
result->_deprecated_sourceDeviceId = self.deprecated_sourceDeviceId;
result->_incomingMessageSchemaVersion = self.incomingMessageSchemaVersion;
result->_read = self.read;
result->_serverDeliveryTimestamp = self.serverDeliveryTimestamp;
result->_serverGuid = self.serverGuid;
@ -187,8 +111,6 @@ const NSUInteger TSIncomingMessageSchemaVersion = 1;
_serverGuid = incomingMessageBuilder.serverGuid;
_wasReceivedByUD = incomingMessageBuilder.wasReceivedByUD;
_incomingMessageSchemaVersion = TSIncomingMessageSchemaVersion;
return self;
}

View File

@ -27,23 +27,23 @@ extension TSInfoMessage {
private static let messagesKey = "messagesKey"
public func encode(with aCoder: NSCoder) {
public func encode(with coder: NSCoder) {
let jsonEncoder = JSONEncoder()
do {
let messagesData = try jsonEncoder.encode(updateItems)
aCoder.encode(messagesData, forKey: Self.messagesKey)
coder.encode(messagesData, forKey: Self.messagesKey)
} catch let error {
owsFailDebug("Failed to encode updateItems data: \(error)")
return
}
}
public required init?(coder aDecoder: NSCoder) {
public required init?(coder: NSCoder) {
guard
let updateItemsData = aDecoder.decodeObject(
let updateItemsData = coder.decodeObject(
of: NSData.self,
forKey: Self.messagesKey,
)
) as Data?
else {
owsFailDebug("Failed to decode updateItems data")
return nil
@ -53,7 +53,7 @@ extension TSInfoMessage {
do {
updateItems = try jsonDecoder.decode(
[LegacyPersistableGroupUpdateItem].self,
from: updateItemsData as Data,
from: updateItemsData,
)
} catch let error {
owsFailDebug("Failed to decode updateItems data: \(error)")
@ -84,23 +84,23 @@ extension TSInfoMessage {
private static let messagesKey = "messagesKey"
public func encode(with aCoder: NSCoder) {
public func encode(with coder: NSCoder) {
let jsonEncoder = JSONEncoder()
do {
let messagesData = try jsonEncoder.encode(updateItems)
aCoder.encode(messagesData, forKey: Self.messagesKey)
coder.encode(messagesData, forKey: Self.messagesKey)
} catch let error {
owsFailDebug("Failed to encode updateItems data: \(error)")
return
}
}
public required init?(coder aDecoder: NSCoder) {
public required init?(coder: NSCoder) {
guard
let updateItemsData = aDecoder.decodeObject(
let updateItemsData = coder.decodeObject(
of: NSData.self,
forKey: Self.messagesKey,
)
) as Data?
else {
owsFailDebug("Failed to decode updateItems data")
return nil
@ -110,7 +110,7 @@ extension TSInfoMessage {
do {
updateItems = try jsonDecoder.decode(
[PersistableGroupUpdateItem].self,
from: updateItemsData as Data,
from: updateItemsData,
)
} catch let error {
owsFailDebug("Failed to decode updateItems data: \(error)")

View File

@ -118,7 +118,9 @@ public extension TSInfoMessage {
// MARK: -
/// Represents a profile change for in-chat messages.
public final class ProfileChanges: NSObject, NSCoding, NSCopying {
public final class ProfileChanges: NSObject, NSSecureCoding, NSCopying {
public static var supportsSecureCoding: Bool { true }
public init?(coder: NSCoder) {
self.address = coder.decodeObject(of: SignalServiceAddress.self, forKey: "address")
self.newNameComponents = coder.decodeObject(of: NSPersonNameComponents.self, forKey: "newNameComponents") as PersonNameComponents?

View File

@ -86,6 +86,7 @@ extern InfoMessageUserInfoKey const InfoMessageUserInfoKeyPinnedMessage;
@property (nonatomic, readonly, nullable) SignalServiceAddress *unregisteredAddress;
@property (nonatomic, readonly, nullable) NSString *serverGuid;
+ (NSArray<Class> *)infoMessageUserInfoObjectClasses;
@property (nonatomic, nullable) NSDictionary<InfoMessageUserInfoKey, id> *infoMessageUserInfo;
- (instancetype)initMessageWithBuilder:(TSMessageBuilder *)messageBuilder NS_UNAVAILABLE;
@ -120,7 +121,7 @@ extern InfoMessageUserInfoKey const InfoMessageUserInfoKeyPinnedMessage;
storyTimestamp:(nullable NSNumber *)storyTimestamp
wasRemotelyDeleted:(BOOL)wasRemotelyDeleted NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
- (instancetype)initWithThread:(TSThread *)thread
timestamp:(uint64_t)timestamp

View File

@ -39,55 +39,19 @@ const InfoMessageUserInfoKey InfoMessageUserInfoKeyUsernameDisplayNameBeforeLear
const InfoMessageUserInfoKey InfoMessageUserInfoKeyEndPoll = @"InfoMessageUserInfoKeyEndPoll";
const InfoMessageUserInfoKey InfoMessageUserInfoKeyPinnedMessage = @"InfoMessageUserInfoKeyPinnedMessage";
NSUInteger TSInfoMessageSchemaVersion = 2;
@interface TSInfoMessage ()
@property (nonatomic, getter=wasRead) BOOL read;
@property (nonatomic, readonly) NSUInteger infoMessageSchemaVersion;
@end
#pragma mark -
@implementation TSInfoMessage
- (void)encodeWithCoder:(NSCoder *)coder
+ (NSArray<Class> *)infoMessageUserInfoObjectClasses
{
[super encodeWithCoder:coder];
NSString *customMessage = self.customMessage;
if (customMessage != nil) {
[coder encodeObject:customMessage forKey:@"customMessage"];
}
[coder encodeObject:[self valueForKey:@"infoMessageSchemaVersion"] forKey:@"infoMessageSchemaVersion"];
NSDictionary *infoMessageUserInfo = self.infoMessageUserInfo;
if (infoMessageUserInfo != nil) {
[coder encodeObject:infoMessageUserInfo forKey:@"infoMessageUserInfo"];
}
[coder encodeObject:[self valueForKey:@"messageType"] forKey:@"messageType"];
[coder encodeObject:[self valueForKey:@"read"] forKey:@"read"];
NSString *serverGuid = self.serverGuid;
if (serverGuid != nil) {
[coder encodeObject:serverGuid forKey:@"serverGuid"];
}
SignalServiceAddress *unregisteredAddress = self.unregisteredAddress;
if (unregisteredAddress != nil) {
[coder encodeObject:unregisteredAddress forKey:@"unregisteredAddress"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_customMessage = [coder decodeObjectOfClass:[NSString class] forKey:@"customMessage"];
self->_infoMessageSchemaVersion =
[(NSNumber *)[coder decodeObjectOfClass:[NSNumber class]
forKey:@"infoMessageSchemaVersion"] unsignedIntegerValue];
self->_infoMessageUserInfo = [coder decodeObjectOfClasses:[NSSet setWithArray:@[
return @[
[DisappearingMessageToken class],
[NSDictionary class],
[NSNull class],
@ -100,38 +64,13 @@ NSUInteger TSInfoMessageSchemaVersion = 2;
[TSGroupModel class],
[TSInfoMessageUpdateMessages class],
[TSInfoMessageUpdateMessagesV2 class]
]]
forKey:@"infoMessageUserInfo"];
self->_messageType = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"messageType"] integerValue];
self->_read = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"read"] boolValue];
self->_serverGuid = [coder decodeObjectOfClass:[NSString class] forKey:@"serverGuid"];
self->_unregisteredAddress = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"unregisteredAddress"];
if (self.infoMessageSchemaVersion < 1) {
_read = YES;
}
if (self.infoMessageSchemaVersion < 2) {
NSString *_Nullable phoneNumber = [coder decodeObjectForKey:@"unregisteredRecipientId"];
if (phoneNumber) {
_unregisteredAddress = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber];
}
}
_infoMessageSchemaVersion = TSInfoMessageSchemaVersion;
if (self.isDynamicInteraction) {
self.read = YES;
}
return self;
];
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];
result ^= self.customMessage.hash;
result ^= self.infoMessageSchemaVersion;
result ^= self.infoMessageUserInfo.hash;
result ^= (NSUInteger)self.messageType;
result ^= self.read;
@ -149,9 +88,6 @@ NSUInteger TSInfoMessageSchemaVersion = 2;
if (![NSObject isObject:self.customMessage equalToObject:typedOther.customMessage]) {
return NO;
}
if (self.infoMessageSchemaVersion != typedOther.infoMessageSchemaVersion) {
return NO;
}
if (![NSObject isObject:self.infoMessageUserInfo equalToObject:typedOther.infoMessageUserInfo]) {
return NO;
}
@ -174,7 +110,6 @@ NSUInteger TSInfoMessageSchemaVersion = 2;
{
TSInfoMessage *result = [super copyWithZone:zone];
result->_customMessage = self.customMessage;
result->_infoMessageSchemaVersion = self.infoMessageSchemaVersion;
result->_infoMessageUserInfo = self.infoMessageUserInfo;
result->_messageType = self.messageType;
result->_read = self.read;
@ -211,7 +146,6 @@ NSUInteger TSInfoMessageSchemaVersion = 2;
_serverGuid = serverGuid;
_messageType = messageType;
_infoMessageUserInfo = infoMessageUserInfo;
_infoMessageSchemaVersion = TSInfoMessageSchemaVersion;
if (self.isDynamicInteraction) {
self.read = YES;

View File

@ -35,10 +35,11 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value);
#pragma mark -
@interface TSInteraction : BaseModel <NSCoding, NSCopying>
@interface TSInteraction : BaseModel <NSCopying>
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
- (void)encodeWithCoder:(NSCoder *)coder;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithUniqueId:(NSString *)uniqueId NS_UNAVAILABLE;
- (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId NS_UNAVAILABLE;

View File

@ -155,9 +155,9 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
if (_receivedAtTimestamp == 0) {
// Upgrade from the older "TSMessage.receivedAtDate" and "TSMessage.receivedAt" properties if
// necessary.
NSDate *receivedAtDate = [coder decodeObjectForKey:@"receivedAtDate"];
NSDate *receivedAtDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"receivedAtDate"];
if (!receivedAtDate) {
receivedAtDate = [coder decodeObjectForKey:@"receivedAt"];
receivedAtDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"receivedAt"];
}
if (receivedAtDate) {

View File

@ -300,7 +300,9 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
if (_schemaVersion < 2) {
// renamed _attachments to _attachmentIds
if (!_deprecated_attachmentIds) {
_deprecated_attachmentIds = [coder decodeObjectForKey:@"attachments"];
_deprecated_attachmentIds =
[coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], [NSString class] ]]
forKey:@"attachments"];
}
}
@ -340,11 +342,12 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
// per-message expiration was never released to
// production.
NSNumber *_Nullable perMessageExpirationDurationSeconds =
[coder decodeObjectForKey:@"perMessageExpirationDurationSeconds"];
[coder decodeObjectOfClass:[NSNumber class] forKey:@"perMessageExpirationDurationSeconds"];
if (perMessageExpirationDurationSeconds.unsignedIntegerValue > 0) {
_isViewOnceMessage = YES;
}
NSNumber *_Nullable perMessageExpirationHasExpired = [coder decodeObjectForKey:@"perMessageExpirationHasExpired"];
NSNumber *_Nullable perMessageExpirationHasExpired = [coder decodeObjectOfClass:[NSNumber class]
forKey:@"perMessageExpirationHasExpired"];
if (perMessageExpirationHasExpired.boolValue > 0) {
_isViewOnceComplete = YES;
}

View File

@ -43,6 +43,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -65,7 +65,7 @@ typedef NS_ENUM(NSInteger, EncryptionStyle) {
#pragma mark -
@interface TSOutgoingMessage : TSMessage
@interface TSOutgoingMessage : TSMessage <NSSecureCoding>
- (instancetype)initMessageWithBuilder:(TSMessageBuilder *)messageBuilder NS_UNAVAILABLE;

View File

@ -166,6 +166,11 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1;
// --- CODE GENERATION MARKER
+ (BOOL)supportsSecureCoding
{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];

View File

@ -4,7 +4,7 @@
//
@objc(TSOutgoingMessageRecipientState)
public final class TSOutgoingMessageRecipientState: NSObject, NSCoding, NSCopying {
public final class TSOutgoingMessageRecipientState: NSObject, NSSecureCoding, NSCopying {
/// The status of the outgoing message send to this recipient.
public private(set) var status: OWSOutgoingMessageRecipientStatus
@ -88,7 +88,7 @@ public final class TSOutgoingMessageRecipientState: NSObject, NSCoding, NSCopyin
}
}
// MARK: - NSCoding
// MARK: - NSSecureCoding
fileprivate enum CoderKeys: String {
case status = "state"
@ -97,9 +97,11 @@ public final class TSOutgoingMessageRecipientState: NSObject, NSCoding, NSCopyin
case errorCode
}
public static var supportsSecureCoding: Bool { true }
public required init?(coder: NSCoder) {
guard
let statusRawValue = coder.decodeObject(of: NSNumber.self, forCoderKey: .status) as? UInt,
let statusRawValue = coder.decodeObject(of: NSNumber.self, forCoderKey: .status)?.uintValue,
let status = OWSOutgoingMessageRecipientStatus(rawValue: statusRawValue)
else {
owsFailDebug("Missing or unrecognized fields!")
@ -170,14 +172,14 @@ public final class TSOutgoingMessageRecipientState: NSObject, NSCoding, NSCopyin
// MARK: -
private extension NSCoder {
func decodeObject<DecodedObjectType: NSObject & NSCoding>(
func decodeObject<DecodedObjectType: NSObject & NSSecureCoding>(
of cls: DecodedObjectType.Type,
forCoderKey key: TSOutgoingMessageRecipientState.CoderKeys,
) -> DecodedObjectType? {
return decodeObject(of: cls, forKey: key.rawValue)
}
func encode<EncodedObjectType: NSObject & NSCoding>(
func encode<EncodedObjectType: NSObject & NSSecureCoding>(
_ object: EncodedObjectType,
forCoderKey key: TSOutgoingMessageRecipientState.CoderKeys,
) {

View File

@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
timestamp:(uint64_t)timestamp
uniqueThreadId:(NSString *)uniqueThreadId NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
// --- CODE GENERATION MARKER

View File

@ -24,11 +24,6 @@ NS_ASSUME_NONNULL_BEGIN
uniqueThreadId:uniqueThreadId];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
return [super initWithCoder:coder];
}
- (BOOL)shouldUseReceiptDateForSorting
{
// Use the timestamp, not the "received at" timestamp to sort,

View File

@ -11,8 +11,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithGrdbId:(int64_t)grdbId
uniqueId:(NSString *)uniqueId
receivedAtTimestamp:(uint64_t)receivedAtTimestamp

View File

@ -9,11 +9,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation TSInvalidIdentityKeyErrorMessage
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
return [super initWithCoder:coder];
}
- (SignalServiceAddress *)theirSignalAddress
{
OWSAbstractMethod();

View File

@ -14,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
// around to honor their old behavior.
/* DEPRECATED */ @interface TSInvalidIdentityKeyReceivingErrorMessage : TSInvalidIdentityKeyErrorMessage
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithGrdbId:(int64_t)grdbId
uniqueId:(NSString *)uniqueId
receivedAtTimestamp:(uint64_t)receivedAtTimestamp

View File

@ -20,34 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark -
@implementation TSInvalidIdentityKeyReceivingErrorMessage {
// Not using a property declaration in order to exclude from DB serialization
SSKProtoEnvelope *_Nullable _envelope;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSString *authorId = self.authorId;
if (authorId != nil) {
[coder encodeObject:authorId forKey:@"authorId"];
}
NSData *envelopeData = self.envelopeData;
if (envelopeData != nil) {
[coder encodeObject:envelopeData forKey:@"envelopeData"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_authorId = [coder decodeObjectOfClass:[NSString class] forKey:@"authorId"];
self->_envelopeData = [coder decodeObjectOfClass:[NSData class] forKey:@"envelopeData"];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];

View File

@ -17,8 +17,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSString *messageId;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithGrdbId:(int64_t)grdbId
uniqueId:(NSString *)uniqueId
receivedAtTimestamp:(uint64_t)receivedAtTimestamp

View File

@ -25,30 +25,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation TSInvalidIdentityKeySendingErrorMessage
#pragma clang diagnostic pop
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSString *messageId = self.messageId;
if (messageId != nil) {
[coder encodeObject:messageId forKey:@"messageId"];
}
NSData *preKeyBundle = self.preKeyBundle;
if (preKeyBundle != nil) {
[coder encodeObject:preKeyBundle forKey:@"preKeyBundle"];
}
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
self->_messageId = [coder decodeObjectOfClass:[NSString class] forKey:@"messageId"];
self->_preKeyBundle = [coder decodeObjectOfClass:[NSData class] forKey:@"preKeyBundle"];
return self;
}
- (NSUInteger)hash
{
NSUInteger result = [super hash];

Some files were not shown because too many files have changed in this diff Show More