diff --git a/Scripts/sds_codegen/sds_generate.py b/Scripts/sds_codegen/sds_generate.py index e8c02310fa..d839612fd3 100755 --- a/Scripts/sds_codegen/sds_generate.py +++ b/Scripts/sds_codegen/sds_generate.py @@ -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 [ diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index ef36f7dea4..754428bdaf 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -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 = ""; }; 507D614C2BE433EE00DA7BA3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = translations/be.lproj/Localizable.strings; sourceTree = ""; }; 507D614D2BE433EE00DA7BA3 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = be; path = translations/be.lproj/PluralAware.stringsdict; sourceTree = ""; }; - 507E1BDE2A0E13B100650611 /* NSKeyedUnarchiver+SSK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSKeyedUnarchiver+SSK.swift"; sourceTree = ""; }; 508347052AABBF9900DD2EC0 /* ProfileManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileManagerTest.swift; sourceTree = ""; }; 508622AC2D026F5200931BF9 /* CanonicalPhoneNumberTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CanonicalPhoneNumberTest.swift; sourceTree = ""; }; 508C72232C2DFCB2000811F3 /* OWSOutgoingResendResponseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSOutgoingResendResponseTest.swift; sourceTree = ""; }; @@ -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 */, diff --git a/Signal/ConversationView/DynamicInteractions/DateHeaderInteraction.swift b/Signal/ConversationView/DynamicInteractions/DateHeaderInteraction.swift index 2cc138c91a..83886307f6 100644 --- a/Signal/ConversationView/DynamicInteractions/DateHeaderInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/DateHeaderInteraction.swift @@ -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. diff --git a/Signal/ConversationView/DynamicInteractions/DefaultDisappearingMessageTimerInteraction.swift b/Signal/ConversationView/DynamicInteractions/DefaultDisappearingMessageTimerInteraction.swift index fa0908bb3e..295e267da6 100644 --- a/Signal/ConversationView/DynamicInteractions/DefaultDisappearingMessageTimerInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/DefaultDisappearingMessageTimerInteraction.swift @@ -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. diff --git a/Signal/ConversationView/DynamicInteractions/ThreadDetailsInteraction.swift b/Signal/ConversationView/DynamicInteractions/ThreadDetailsInteraction.swift index 1fc22d8c53..5ba2c722da 100644 --- a/Signal/ConversationView/DynamicInteractions/ThreadDetailsInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/ThreadDetailsInteraction.swift @@ -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. diff --git a/Signal/ConversationView/DynamicInteractions/TypingIndicatorInteraction.swift b/Signal/ConversationView/DynamicInteractions/TypingIndicatorInteraction.swift index 55c785f685..3221e571a2 100644 --- a/Signal/ConversationView/DynamicInteractions/TypingIndicatorInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/TypingIndicatorInteraction.swift @@ -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) { diff --git a/Signal/ConversationView/DynamicInteractions/UnknownThreadWarningInteraction.swift b/Signal/ConversationView/DynamicInteractions/UnknownThreadWarningInteraction.swift index 010eb68069..2fa0216105 100644 --- a/Signal/ConversationView/DynamicInteractions/UnknownThreadWarningInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/UnknownThreadWarningInteraction.swift @@ -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. diff --git a/Signal/ConversationView/DynamicInteractions/UnreadIndicatorInteraction.swift b/Signal/ConversationView/DynamicInteractions/UnreadIndicatorInteraction.swift index 439f1f0b7b..e0d206cdb5 100644 --- a/Signal/ConversationView/DynamicInteractions/UnreadIndicatorInteraction.swift +++ b/Signal/ConversationView/DynamicInteractions/UnreadIndicatorInteraction.swift @@ -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. diff --git a/Signal/Storage/InfoMessageGroupUpdateMigrator.swift b/Signal/Storage/InfoMessageGroupUpdateMigrator.swift index 01796a6b1a..00cb63a292 100644 --- a/Signal/Storage/InfoMessageGroupUpdateMigrator.swift +++ b/Signal/Storage/InfoMessageGroupUpdateMigrator.swift @@ -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( diff --git a/Signal/src/views/MockConversationView.swift b/Signal/src/views/MockConversationView.swift index 1349fe8a6b..839649978a 100644 --- a/Signal/src/views/MockConversationView.swift +++ b/Signal/src/views/MockConversationView.swift @@ -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 } diff --git a/Signal/test/Storage/InfoMessageGroupUpdateMigratorTest.swift b/Signal/test/Storage/InfoMessageGroupUpdateMigratorTest.swift index dcef0843cb..b5aa13f2be 100644 --- a/Signal/test/Storage/InfoMessageGroupUpdateMigratorTest.swift +++ b/Signal/test/Storage/InfoMessageGroupUpdateMigratorTest.swift @@ -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) } } diff --git a/SignalServiceKit/Calls/Group/OWSGroupCallMessage.h b/SignalServiceKit/Calls/Group/OWSGroupCallMessage.h index 013919df8a..46a4539954 100644 --- a/SignalServiceKit/Calls/Group/OWSGroupCallMessage.h +++ b/SignalServiceKit/Calls/Group/OWSGroupCallMessage.h @@ -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 *)joinedMemberAcis creatorAci:(nullable AciObjC *)creatorAci diff --git a/SignalServiceKit/Calls/Group/OWSGroupCallMessage.m b/SignalServiceKit/Calls/Group/OWSGroupCallMessage.m index b4cec3f1e7..c3de9209d1 100644 --- a/SignalServiceKit/Calls/Group/OWSGroupCallMessage.m +++ b/SignalServiceKit/Calls/Group/OWSGroupCallMessage.m @@ -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]; diff --git a/SignalServiceKit/Calls/Group/OutgoingGroupCallUpdateMessage.swift b/SignalServiceKit/Calls/Group/OutgoingGroupCallUpdateMessage.swift index 4f24f00e25..b267e11e7d 100644 --- a/SignalServiceKit/Calls/Group/OutgoingGroupCallUpdateMessage.swift +++ b/SignalServiceKit/Calls/Group/OutgoingGroupCallUpdateMessage.swift @@ -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) diff --git a/SignalServiceKit/Calls/Individual/TSCall.h b/SignalServiceKit/Calls/Individual/TSCall.h index 4bff5ff74b..e9589a279e 100644 --- a/SignalServiceKit/Calls/Individual/TSCall.h +++ b/SignalServiceKit/Calls/Individual/TSCall.h @@ -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 diff --git a/SignalServiceKit/Calls/Individual/TSCall.m b/SignalServiceKit/Calls/Individual/TSCall.m index a9b625a10e..edefde1f8e 100644 --- a/SignalServiceKit/Calls/Individual/TSCall.m +++ b/SignalServiceKit/Calls/Individual/TSCall.m @@ -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; diff --git a/SignalServiceKit/Calls/OWSOutgoingCallMessage.m b/SignalServiceKit/Calls/OWSOutgoingCallMessage.m index b89b0ae152..9c40e01dde 100644 --- a/SignalServiceKit/Calls/OWSOutgoingCallMessage.m +++ b/SignalServiceKit/Calls/OWSOutgoingCallMessage.m @@ -28,6 +28,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Calls/OutgoingCallEventSyncMessage.swift b/SignalServiceKit/Calls/OutgoingCallEventSyncMessage.swift index b227d70ec1..a7a7b2d00e 100644 --- a/SignalServiceKit/Calls/OutgoingCallEventSyncMessage.swift +++ b/SignalServiceKit/Calls/OutgoingCallEventSyncMessage.swift @@ -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) diff --git a/SignalServiceKit/Calls/OutgoingCallLinkUpdateMessage.swift b/SignalServiceKit/Calls/OutgoingCallLinkUpdateMessage.swift index 716981f872..15d07a2c57 100644 --- a/SignalServiceKit/Calls/OutgoingCallLinkUpdateMessage.swift +++ b/SignalServiceKit/Calls/OutgoingCallLinkUpdateMessage.swift @@ -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? diff --git a/SignalServiceKit/Calls/OutgoingCallLogEventSyncMessage.swift b/SignalServiceKit/Calls/OutgoingCallLogEventSyncMessage.swift index 721cbcefff..cb03f28fe3 100644 --- a/SignalServiceKit/Calls/OutgoingCallLogEventSyncMessage.swift +++ b/SignalServiceKit/Calls/OutgoingCallLogEventSyncMessage.swift @@ -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 diff --git a/SignalServiceKit/Contacts/ContactTest.swift b/SignalServiceKit/Contacts/ContactTest.swift index 38cda0db53..8ac000ca08 100644 --- a/SignalServiceKit/Contacts/ContactTest.swift +++ b/SignalServiceKit/Contacts/ContactTest.swift @@ -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") diff --git a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.h b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.h index b87779b467..2c1c506bc9 100644 --- a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.h +++ b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.h @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @class DBReadTransaction; @class TSThread; -@interface OWSDisappearingMessagesConfiguration : BaseModel +@interface OWSDisappearingMessagesConfiguration : BaseModel + (instancetype)new NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; diff --git a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.m b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.m index 84b0a6b193..d36203f69d 100644 --- a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.m +++ b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.m @@ -20,6 +20,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSDisappearingMessagesConfiguration ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [self encodeIdsWithCoder:coder]; diff --git a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.swift b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.swift index 11d4fde6da..f74ffa5408 100644 --- a/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.swift +++ b/SignalServiceKit/Contacts/OWSDisappearingMessagesConfiguration.swift @@ -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 } diff --git a/SignalServiceKit/Contacts/TSThread+SDS.swift b/SignalServiceKit/Contacts/TSThread+SDS.swift index 3c30042fa7..3a84fbdbb1 100644 --- a/SignalServiceKit/Contacts/TSThread+SDS.swift +++ b/SignalServiceKit/Contacts/TSThread+SDS.swift @@ -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 diff --git a/SignalServiceKit/Contacts/TSThread.h b/SignalServiceKit/Contacts/TSThread.h index 5a2fca33f0..ed11301ad0 100644 --- a/SignalServiceKit/Contacts/TSThread.h +++ b/SignalServiceKit/Contacts/TSThread.h @@ -33,7 +33,7 @@ typedef NS_CLOSED_ENUM(NSUInteger, TSThreadStoryViewMode) { /** * TSThread is the superclass of TSContactThread, TSGroupThread, and TSPrivateStoryThread */ -@interface TSThread : BaseModel +@interface TSThread : BaseModel @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 diff --git a/SignalServiceKit/Contacts/TSThread.m b/SignalServiceKit/Contacts/TSThread.m index bed4f6a9b2..fc8c388e22 100644 --- a/SignalServiceKit/Contacts/TSThread.m +++ b/SignalServiceKit/Contacts/TSThread.m @@ -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 *)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 diff --git a/SignalServiceKit/Devices/SyncMessages/OWSBlockedPhoneNumbersMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSBlockedPhoneNumbersMessage.m index 9b2bb292b4..3c682ddafe 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSBlockedPhoneNumbersMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSBlockedPhoneNumbersMessage.m @@ -18,6 +18,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSBlockedPhoneNumbersMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.h b/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.h index ca94d520e2..c5f58d1c12 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.h +++ b/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @class DBReadTransaction; @class SignalServiceAddress; -@interface OWSLinkedDeviceReadReceipt : NSObject +@interface OWSLinkedDeviceReadReceipt : NSObject @property (nonatomic, readonly) SignalServiceAddress *senderAddress; @property (nonatomic, readonly, nullable) NSString *messageUniqueId; // Only nil if decoding old values diff --git a/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.m b/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.m index 29491a6975..a45c60b60a 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSLinkedDeviceReadReceipt.m @@ -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); } diff --git a/SignalServiceKit/Devices/SyncMessages/OWSReadReceiptsForLinkedDevicesMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSReadReceiptsForLinkedDevicesMessage.m index 9d719f1085..35791a7688 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSReadReceiptsForLinkedDevicesMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSReadReceiptsForLinkedDevicesMessage.m @@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Devices/SyncMessages/OWSReceiptsForSenderMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSReceiptsForSenderMessage.m index a20f5a54cc..a7489253ee 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSReceiptsForSenderMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSReceiptsForSenderMessage.m @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @interface OWSReceiptsForSenderMessage () @property (nonatomic, readonly, nullable) NSSet *messageUniqueIds; -@property (nonatomic, readonly) NSArray *messageTimestamps; +@property (nonatomic, readonly) NSSet *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"]; diff --git a/SignalServiceKit/Devices/SyncMessages/OWSStickerPackSyncMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSStickerPackSyncMessage.m index e8360d309a..3233e6bb8a 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSStickerPackSyncMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSStickerPackSyncMessage.m @@ -19,6 +19,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSStickerPackSyncMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Devices/SyncMessages/OWSVerificationStateSyncMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSVerificationStateSyncMessage.m index b830f832e2..cecd860bab 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSVerificationStateSyncMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSVerificationStateSyncMessage.m @@ -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); diff --git a/SignalServiceKit/Devices/SyncMessages/OWSViewOnceMessageReadSyncMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSViewOnceMessageReadSyncMessage.m index dbaabd10ad..14e88ee0d4 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSViewOnceMessageReadSyncMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSViewOnceMessageReadSyncMessage.m @@ -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); } diff --git a/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.h b/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.h index b6582eefcb..274270e4af 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.h +++ b/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN @class DBReadTransaction; @class SignalServiceAddress; -@interface OWSLinkedDeviceViewedReceipt : NSObject +@interface OWSLinkedDeviceViewedReceipt : NSObject @property (nonatomic, readonly) SignalServiceAddress *senderAddress; @property (nonatomic, readonly, nullable) NSString *messageUniqueId; // Only nil if decoding old values diff --git a/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.m b/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.m index e7cdfdd370..64ba41707a 100644 --- a/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.m +++ b/SignalServiceKit/Devices/SyncMessages/OWSViewedReceiptsForLinkedDevicesMessage.m @@ -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"]; diff --git a/SignalServiceKit/Devices/SyncMessages/OutgoingDeviceNameChangeSyncMessage.swift b/SignalServiceKit/Devices/SyncMessages/OutgoingDeviceNameChangeSyncMessage.swift index f5cc3be98c..b71b8b758f 100644 --- a/SignalServiceKit/Devices/SyncMessages/OutgoingDeviceNameChangeSyncMessage.swift +++ b/SignalServiceKit/Devices/SyncMessages/OutgoingDeviceNameChangeSyncMessage.swift @@ -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) diff --git a/SignalServiceKit/Groups/GroupAccess.swift b/SignalServiceKit/Groups/GroupAccess.swift index 57090f59fc..b2b0274781 100644 --- a/SignalServiceKit/Groups/GroupAccess.swift +++ b/SignalServiceKit/Groups/GroupAccess.swift @@ -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 diff --git a/SignalServiceKit/Groups/GroupMembership.swift b/SignalServiceKit/Groups/GroupMembership.swift index a5fd4b99b9..2c10626b02 100644 --- a/SignalServiceKit/Groups/GroupMembership.swift +++ b/SignalServiceKit/Groups/GroupMembership.swift @@ -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 diff --git a/SignalServiceKit/Groups/TSGroupModel.h b/SignalServiceKit/Groups/TSGroupModel.h index f93eb8479c..a617f19d60 100644 --- a/SignalServiceKit/Groups/TSGroupModel.h +++ b/SignalServiceKit/Groups/TSGroupModel.h @@ -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 +@interface TSGroupModel : NSObject // groupMembers includes administrators and normal members. @property (nonatomic, readonly) NSArray *groupMembers; diff --git a/SignalServiceKit/Groups/TSGroupModel.m b/SignalServiceKit/Groups/TSGroupModel.m index e93e007ea3..153caa3bed 100644 --- a/SignalServiceKit/Groups/TSGroupModel.m +++ b/SignalServiceKit/Groups/TSGroupModel.m @@ -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 *_Nullable memberE164s = [coder decodeObjectForKey:@"groupMemberIds"]; + NSArray *_Nullable memberE164s = + [coder decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], [NSString class] ]] + forKey:@"groupMemberIds"]; if (memberE164s) { NSMutableArray *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; diff --git a/SignalServiceKit/Groups/TSGroupModel.swift b/SignalServiceKit/Groups/TSGroupModel.swift index 3b870b6373..d19345b39f 100644 --- a/SignalServiceKit/Groups/TSGroupModel.swift +++ b/SignalServiceKit/Groups/TSGroupModel.swift @@ -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 diff --git a/SignalServiceKit/Jobs/JobRecords/MessageSenderJobRecord.swift b/SignalServiceKit/Jobs/JobRecords/MessageSenderJobRecord.swift index 29c0237a4e..5dbacb9ac3 100644 --- a/SignalServiceKit/Jobs/JobRecords/MessageSenderJobRecord.swift +++ b/SignalServiceKit/Jobs/JobRecords/MessageSenderJobRecord.swift @@ -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) diff --git a/SignalServiceKit/Messages/BodyRanges/MessageBodyRanges.swift b/SignalServiceKit/Messages/BodyRanges/MessageBodyRanges.swift index 9f04b114fb..92f807ddb0 100644 --- a/SignalServiceKit/Messages/BodyRanges/MessageBodyRanges.swift +++ b/SignalServiceKit/Messages/BodyRanges/MessageBodyRanges.swift @@ -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, diff --git a/SignalServiceKit/Messages/DeviceSyncing/DeleteForMe/DeleteForMeOutgoingSyncMessage.swift b/SignalServiceKit/Messages/DeviceSyncing/DeleteForMe/DeleteForMeOutgoingSyncMessage.swift index ed5a07a0d7..0502ed3879 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/DeleteForMe/DeleteForMeOutgoingSyncMessage.swift +++ b/SignalServiceKit/Messages/DeviceSyncing/DeleteForMe/DeleteForMeOutgoingSyncMessage.swift @@ -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) diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m b/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m index ed317b34bc..6e60829118 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSentMessageTranscript.m @@ -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 diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m index bdffa5f6f2..97064edcfa 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSOutgoingSyncMessage.m @@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSOutgoingSyncMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (nullable instancetype)initWithCoder:(NSCoder *)coder { return [super initWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncConfigurationMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncConfigurationMessage.m index b081c825c0..d4a00ecfda 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncConfigurationMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncConfigurationMessage.m @@ -42,6 +42,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncFetchLatestMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncFetchLatestMessage.m index 2a8b44b84b..2bc4a87456 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncFetchLatestMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncFetchLatestMessage.m @@ -28,6 +28,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncKeysMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncKeysMessage.m index 571788a027..8e7379b0e9 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncKeysMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncKeysMessage.m @@ -36,6 +36,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncMessageRequestResponseMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncMessageRequestResponseMessage.m index 518705f7f6..923df5fe43 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncMessageRequestResponseMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncMessageRequestResponseMessage.m @@ -25,6 +25,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSSyncMessageRequestResponseMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncRequestMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncRequestMessage.m index 8f2000ab04..4444b84714 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OWSSyncRequestMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OWSSyncRequestMessage.m @@ -35,6 +35,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.h b/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.h index 4e6dd83af4..8630f9dfda 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.h +++ b/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @class AciObjC; -@interface OutgoingPaymentMobileCoin : NSObject +@interface OutgoingPaymentMobileCoin : NSObject @property (nonatomic, readonly, nullable) AciObjC *recipientAci; @property (nonatomic, readonly, nullable) NSData *recipientAddress; diff --git a/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.m b/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.m index 2752ea8f93..bcebf2eedb 100644 --- a/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.m +++ b/SignalServiceKit/Messages/DeviceSyncing/OutgoingPaymentSyncMessage.m @@ -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]; diff --git a/SignalServiceKit/Messages/Edit/OutgoingEditMessage.swift b/SignalServiceKit/Messages/Edit/OutgoingEditMessage.swift index 45c3c6c092..3c8ba1ac3b 100644 --- a/SignalServiceKit/Messages/Edit/OutgoingEditMessage.swift +++ b/SignalServiceKit/Messages/Edit/OutgoingEditMessage.swift @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContact.swift b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContact.swift index 0b69479287..6986f13aa4 100644 --- a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContact.swift +++ b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContact.swift @@ -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) { diff --git a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactAddress.swift b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactAddress.swift index 530d33130d..f2a61e408f 100644 --- a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactAddress.swift +++ b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactAddress.swift @@ -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? diff --git a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactEmail.swift b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactEmail.swift index ced49df148..1dadc039dd 100644 --- a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactEmail.swift +++ b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactEmail.swift @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactName.swift b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactName.swift index d769dc45ca..a59f4aad04 100644 --- a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactName.swift +++ b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactName.swift @@ -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? diff --git a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactPhoneNumber.swift b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactPhoneNumber.swift index b0d626f645..38eee2e4e9 100644 --- a/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactPhoneNumber.swift +++ b/SignalServiceKit/Messages/Interactions/ContactShare/OWSContactPhoneNumber.swift @@ -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? ?? "" diff --git a/SignalServiceKit/Messages/Interactions/LinkPreview/OWSLinkPreview.swift b/SignalServiceKit/Messages/Interactions/LinkPreview/OWSLinkPreview.swift index 7c7da2c009..1a5efc57f7 100644 --- a/SignalServiceKit/Messages/Interactions/LinkPreview/OWSLinkPreview.swift +++ b/SignalServiceKit/Messages/Interactions/LinkPreview/OWSLinkPreview.swift @@ -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? diff --git a/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.h b/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.h index 271495a49b..6591301c2d 100644 --- a/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.h +++ b/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.m b/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.m index 62c24234dc..ee108f4e29 100644 --- a/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.m +++ b/SignalServiceKit/Messages/Interactions/OWSDisappearingConfigurationUpdateInfoMessage.m @@ -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]; diff --git a/SignalServiceKit/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m b/SignalServiceKit/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m index 1e76e71e62..c685baeec5 100644 --- a/SignalServiceKit/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m +++ b/SignalServiceKit/Messages/Interactions/OWSDisappearingMessagesConfigurationMessage.m @@ -48,6 +48,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Interactions/OWSEndSessionMessage.m b/SignalServiceKit/Messages/Interactions/OWSEndSessionMessage.m index bbab6903e8..b4d069dc17 100644 --- a/SignalServiceKit/Messages/Interactions/OWSEndSessionMessage.m +++ b/SignalServiceKit/Messages/Interactions/OWSEndSessionMessage.m @@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSEndSessionMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (nullable instancetype)initWithCoder:(NSCoder *)coder { return [super initWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Interactions/OWSGiftBadge.swift b/SignalServiceKit/Messages/Interactions/OWSGiftBadge.swift index 1d1dbc26f6..e223403110 100644 --- a/SignalServiceKit/Messages/Interactions/OWSGiftBadge.swift +++ b/SignalServiceKit/Messages/Interactions/OWSGiftBadge.swift @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/OWSStaticOutgoingMessage.m b/SignalServiceKit/Messages/Interactions/OWSStaticOutgoingMessage.m index 4c1f26c2f8..33001913df 100644 --- a/SignalServiceKit/Messages/Interactions/OWSStaticOutgoingMessage.m +++ b/SignalServiceKit/Messages/Interactions/OWSStaticOutgoingMessage.m @@ -38,6 +38,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.h b/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.h index 132b644d36..0168b4f0c4 100644 --- a/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.h +++ b/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.m b/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.m index 5dc126ff58..2a03ab290d 100644 --- a/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.m +++ b/SignalServiceKit/Messages/Interactions/OWSVerificationStateChangeMessage.m @@ -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]; diff --git a/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingPinMessage.swift b/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingPinMessage.swift index 1ed011d472..7eecee5673 100644 --- a/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingPinMessage.swift +++ b/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingPinMessage.swift @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingUnpinMessage.swift b/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingUnpinMessage.swift index bae0505097..76a4b09a37 100644 --- a/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingUnpinMessage.swift +++ b/SignalServiceKit/Messages/Interactions/PinnedMessages/OutgoingUnpinMessage.swift @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollTerminate.swift b/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollTerminate.swift index 734e3e236f..697c110681 100644 --- a/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollTerminate.swift +++ b/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollTerminate.swift @@ -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) diff --git a/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollVote.swift b/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollVote.swift index 9969be4e8b..6510dfdefd 100644 --- a/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollVote.swift +++ b/SignalServiceKit/Messages/Interactions/Polls/OutgoingPollVote.swift @@ -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) } diff --git a/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.h b/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.h index fcbcd54e36..02e16d27b2 100644 --- a/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.h +++ b/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.h @@ -30,9 +30,8 @@ typedef NS_ENUM(NSUInteger, TSQuotedMessageContentSource) { TSQuotedMessageContentSourceStory }; -@interface OWSAttachmentInfo : NSObject +@interface OWSAttachmentInfo : NSObject @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 +@interface TSQuotedMessage : NSObject @property (nullable, nonatomic, readonly) NSNumber *timestampValue; @property (nonatomic, readonly) SignalServiceAddress *authorAddress; diff --git a/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.m b/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.m index 0709a4cada..94b2d9d5e8 100644 --- a/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.m +++ b/SignalServiceKit/Messages/Interactions/Quotes/TSQuotedMessage.m @@ -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); } diff --git a/SignalServiceKit/Messages/Interactions/TSErrorMessage.h b/SignalServiceKit/Messages/Interactions/TSErrorMessage.h index ddbfa7372a..cc4bf1c817 100644 --- a/SignalServiceKit/Messages/Interactions/TSErrorMessage.h +++ b/SignalServiceKit/Messages/Interactions/TSErrorMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/TSErrorMessage.m b/SignalServiceKit/Messages/Interactions/TSErrorMessage.m index cee2fc20db..fdbc73b703 100644 --- a/SignalServiceKit/Messages/Interactions/TSErrorMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSErrorMessage.m @@ -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) { diff --git a/SignalServiceKit/Messages/Interactions/TSIncomingMessage.h b/SignalServiceKit/Messages/Interactions/TSIncomingMessage.h index 62af4ecc79..bcb463c28a 100644 --- a/SignalServiceKit/Messages/Interactions/TSIncomingMessage.h +++ b/SignalServiceKit/Messages/Interactions/TSIncomingMessage.h @@ -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:)); diff --git a/SignalServiceKit/Messages/Interactions/TSIncomingMessage.m b/SignalServiceKit/Messages/Interactions/TSIncomingMessage.m index 29a91db40a..1ef4e81f70 100644 --- a/SignalServiceKit/Messages/Interactions/TSIncomingMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSIncomingMessage.m @@ -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; } diff --git a/SignalServiceKit/Messages/Interactions/TSInfoMessage+GroupUpdates+PersistableGroupUpdateItem.swift b/SignalServiceKit/Messages/Interactions/TSInfoMessage+GroupUpdates+PersistableGroupUpdateItem.swift index 14193b16ae..c3d1cf4414 100644 --- a/SignalServiceKit/Messages/Interactions/TSInfoMessage+GroupUpdates+PersistableGroupUpdateItem.swift +++ b/SignalServiceKit/Messages/Interactions/TSInfoMessage+GroupUpdates+PersistableGroupUpdateItem.swift @@ -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)") diff --git a/SignalServiceKit/Messages/Interactions/TSInfoMessage+ProfileChanges.swift b/SignalServiceKit/Messages/Interactions/TSInfoMessage+ProfileChanges.swift index 21d85daf89..294af18feb 100644 --- a/SignalServiceKit/Messages/Interactions/TSInfoMessage+ProfileChanges.swift +++ b/SignalServiceKit/Messages/Interactions/TSInfoMessage+ProfileChanges.swift @@ -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? diff --git a/SignalServiceKit/Messages/Interactions/TSInfoMessage.h b/SignalServiceKit/Messages/Interactions/TSInfoMessage.h index efb6681928..92a38eb33f 100644 --- a/SignalServiceKit/Messages/Interactions/TSInfoMessage.h +++ b/SignalServiceKit/Messages/Interactions/TSInfoMessage.h @@ -86,6 +86,7 @@ extern InfoMessageUserInfoKey const InfoMessageUserInfoKeyPinnedMessage; @property (nonatomic, readonly, nullable) SignalServiceAddress *unregisteredAddress; @property (nonatomic, readonly, nullable) NSString *serverGuid; ++ (NSArray *)infoMessageUserInfoObjectClasses; @property (nonatomic, nullable) NSDictionary *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 diff --git a/SignalServiceKit/Messages/Interactions/TSInfoMessage.m b/SignalServiceKit/Messages/Interactions/TSInfoMessage.m index b62720b549..9c713021f8 100644 --- a/SignalServiceKit/Messages/Interactions/TSInfoMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSInfoMessage.m @@ -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 *)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; diff --git a/SignalServiceKit/Messages/Interactions/TSInteraction+SDS.swift b/SignalServiceKit/Messages/Interactions/TSInteraction+SDS.swift index a8919fb55f..6070363c25 100644 --- a/SignalServiceKit/Messages/Interactions/TSInteraction+SDS.swift +++ b/SignalServiceKit/Messages/Interactions/TSInteraction+SDS.swift @@ -318,11 +318,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -331,18 +331,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -350,14 +350,14 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) return OWSAddToContactsOfferMessage(grdbId: recordId, uniqueId: uniqueId, @@ -404,11 +404,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -417,18 +417,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -436,14 +436,14 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) return OWSAddToProfileWhitelistOfferMessage(grdbId: recordId, uniqueId: uniqueId, @@ -490,11 +490,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -503,18 +503,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -522,14 +522,14 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let configurationDurationSeconds: UInt32 = try SDSDeserialization.required(record.configurationDurationSeconds, name: "configurationDurationSeconds") let configurationIsEnabled: Bool = try SDSDeserialization.required(record.configurationIsEnabled, name: "configurationIsEnabled") let createdByRemoteName: String? = record.createdByRemoteName @@ -586,7 +586,7 @@ extension TSInteraction { let eraId: String? = record.eraId let hasEnded: Bool = try SDSDeserialization.required(record.hasEnded, name: "hasEnded") let joinedMemberUuidsSerialized: Data? = record.joinedMemberUuids - let joinedMemberUuids: [String]? = try SDSDeserialization.optionalUnarchive(joinedMemberUuidsSerialized, name: "joinedMemberUuids") + let joinedMemberUuids: [String]? = try joinedMemberUuidsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) let read: Bool = try SDSDeserialization.required(record.read, name: "read") return OWSGroupCallMessage(grdbId: recordId, @@ -610,11 +610,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -623,18 +623,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -649,8 +649,8 @@ extension TSInteraction { let serverTimestamp: NSNumber? = SDSDeserialization.optionalNumericAsNSNumber(record.serverTimestamp, name: "serverTimestamp", conversion: { NSNumber(value: $0) }) let viewed: Bool = try SDSDeserialization.required(record.viewed, name: "viewed") let wasReceivedByUD: Bool = try SDSDeserialization.required(record.wasReceivedByUD, name: "wasReceivedByUD") - let archivedPaymentInfoSerialized: Data? = record.archivedPaymentInfo - let archivedPaymentInfo: TSArchivedPaymentInfo = try SDSDeserialization.unarchive(archivedPaymentInfoSerialized, name: "archivedPaymentInfo") + let archivedPaymentInfoSerialized: Data = try record.archivedPaymentInfo ?? { () -> Data in throw SDSError.missingRequiredField(fieldName: "archivedPaymentInfo") }() + let archivedPaymentInfo: TSArchivedPaymentInfo = try SDSDeserialization.unarchivedObject(ofClass: TSArchivedPaymentInfo.self, from: archivedPaymentInfoSerialized) return OWSIncomingArchivedPaymentMessage(grdbId: recordId, uniqueId: uniqueId, @@ -701,11 +701,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -714,18 +714,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -742,7 +742,7 @@ extension TSInteraction { let wasReceivedByUD: Bool = try SDSDeserialization.required(record.wasReceivedByUD, name: "wasReceivedByUD") let paymentCancellation: Data? = SDSDeserialization.optionalData(record.paymentCancellation, name: "paymentCancellation") let paymentNotificationSerialized: Data? = record.paymentNotification - let paymentNotification: TSPaymentNotification? = try SDSDeserialization.optionalUnarchive(paymentNotificationSerialized, name: "paymentNotification") + let paymentNotification: TSPaymentNotification? = try paymentNotificationSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSPaymentNotification.self, from: $0) }) let paymentRequest: Data? = SDSDeserialization.optionalData(record.paymentRequest, name: "paymentRequest") return OWSIncomingPaymentMessage(grdbId: recordId, @@ -796,11 +796,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -809,18 +809,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -839,13 +839,13 @@ extension TSInteraction { let legacyWasDelivered: Bool = try SDSDeserialization.required(record.legacyWasDelivered, name: "legacyWasDelivered") let mostRecentFailureText: String? = record.mostRecentFailureText let recipientAddressStatesSerialized: Data? = record.recipientAddressStates - let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try SDSDeserialization.optionalUnarchive(recipientAddressStatesSerialized, name: "recipientAddressStates") + let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try recipientAddressStatesSerialized.map({ try SDSDeserialization.unarchivedDictionary(ofKeyClass: SignalServiceAddress.self, objectClass: TSOutgoingMessageRecipientState.self, from: $0) }) guard let storedMessageState: TSOutgoingMessageState = record.storedMessageState else { throw SDSError.missingRequiredField() } let wasNotCreatedLocally: Bool = try SDSDeserialization.required(record.wasNotCreatedLocally, name: "wasNotCreatedLocally") - let archivedPaymentInfoSerialized: Data? = record.archivedPaymentInfo - let archivedPaymentInfo: TSArchivedPaymentInfo = try SDSDeserialization.unarchive(archivedPaymentInfoSerialized, name: "archivedPaymentInfo") + let archivedPaymentInfoSerialized: Data = try record.archivedPaymentInfo ?? { () -> Data in throw SDSError.missingRequiredField(fieldName: "archivedPaymentInfo") }() + let archivedPaymentInfo: TSArchivedPaymentInfo = try SDSDeserialization.unarchivedObject(ofClass: TSArchivedPaymentInfo.self, from: archivedPaymentInfoSerialized) return OWSOutgoingArchivedPaymentMessage(grdbId: recordId, uniqueId: uniqueId, @@ -898,11 +898,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -911,18 +911,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -941,14 +941,14 @@ extension TSInteraction { let legacyWasDelivered: Bool = try SDSDeserialization.required(record.legacyWasDelivered, name: "legacyWasDelivered") let mostRecentFailureText: String? = record.mostRecentFailureText let recipientAddressStatesSerialized: Data? = record.recipientAddressStates - let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try SDSDeserialization.optionalUnarchive(recipientAddressStatesSerialized, name: "recipientAddressStates") + let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try recipientAddressStatesSerialized.map({ try SDSDeserialization.unarchivedDictionary(ofKeyClass: SignalServiceAddress.self, objectClass: TSOutgoingMessageRecipientState.self, from: $0) }) guard let storedMessageState: TSOutgoingMessageState = record.storedMessageState else { throw SDSError.missingRequiredField() } let wasNotCreatedLocally: Bool = try SDSDeserialization.required(record.wasNotCreatedLocally, name: "wasNotCreatedLocally") let paymentCancellation: Data? = SDSDeserialization.optionalData(record.paymentCancellation, name: "paymentCancellation") let paymentNotificationSerialized: Data? = record.paymentNotification - let paymentNotification: TSPaymentNotification? = try SDSDeserialization.optionalUnarchive(paymentNotificationSerialized, name: "paymentNotification") + let paymentNotification: TSPaymentNotification? = try paymentNotificationSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSPaymentNotification.self, from: $0) }) let paymentRequest: Data? = SDSDeserialization.optionalData(record.paymentRequest, name: "paymentRequest") return OWSOutgoingPaymentMessage(grdbId: recordId, @@ -1004,11 +1004,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1017,18 +1017,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1047,7 +1047,7 @@ extension TSInteraction { let legacyWasDelivered: Bool = try SDSDeserialization.required(record.legacyWasDelivered, name: "legacyWasDelivered") let mostRecentFailureText: String? = record.mostRecentFailureText let recipientAddressStatesSerialized: Data? = record.recipientAddressStates - let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try SDSDeserialization.optionalUnarchive(recipientAddressStatesSerialized, name: "recipientAddressStates") + let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try recipientAddressStatesSerialized.map({ try SDSDeserialization.unarchivedDictionary(ofKeyClass: SignalServiceAddress.self, objectClass: TSOutgoingMessageRecipientState.self, from: $0) }) guard let storedMessageState: TSOutgoingMessageState = record.storedMessageState else { throw SDSError.missingRequiredField() } @@ -1103,11 +1103,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1116,18 +1116,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1146,7 +1146,7 @@ extension TSInteraction { let legacyWasDelivered: Bool = try SDSDeserialization.required(record.legacyWasDelivered, name: "legacyWasDelivered") let mostRecentFailureText: String? = record.mostRecentFailureText let recipientAddressStatesSerialized: Data? = record.recipientAddressStates - let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try SDSDeserialization.optionalUnarchive(recipientAddressStatesSerialized, name: "recipientAddressStates") + let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try recipientAddressStatesSerialized.map({ try SDSDeserialization.unarchivedDictionary(ofKeyClass: SignalServiceAddress.self, objectClass: TSOutgoingMessageRecipientState.self, from: $0) }) guard let storedMessageState: TSOutgoingMessageState = record.storedMessageState else { throw SDSError.missingRequiredField() } @@ -1202,11 +1202,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1215,18 +1215,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1237,9 +1237,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") return OWSRecoverableDecryptionPlaceholder(grdbId: recordId, @@ -1286,11 +1286,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1299,18 +1299,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1321,9 +1321,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") return OWSUnknownContactBlockOfferMessage(grdbId: recordId, @@ -1370,11 +1370,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1383,18 +1383,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1402,17 +1402,17 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let protocolVersion: UInt = try SDSDeserialization.required(record.protocolVersion, name: "protocolVersion") let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) return OWSUnknownProtocolVersionMessage(grdbId: recordId, uniqueId: uniqueId, @@ -1461,11 +1461,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1474,18 +1474,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1493,17 +1493,17 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let isLocalChange: Bool = try SDSDeserialization.required(record.isLocalChange, name: "isLocalChange") - let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress = try SDSDeserialization.unarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddressSerialized: Data = try record.recipientAddress ?? { () -> Data in throw SDSError.missingRequiredField(fieldName: "recipientAddress") }() + let recipientAddress: SignalServiceAddress = try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: recipientAddressSerialized) guard let verificationState: OWSVerificationState = record.verificationState else { throw SDSError.missingRequiredField() } @@ -1581,11 +1581,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1594,18 +1594,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1616,9 +1616,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") return TSErrorMessage(grdbId: recordId, @@ -1665,11 +1665,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1678,18 +1678,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1753,11 +1753,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1766,18 +1766,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1785,14 +1785,14 @@ extension TSInteraction { let wasRemotelyDeleted: Bool = try SDSDeserialization.required(record.wasRemotelyDeleted, name: "wasRemotelyDeleted") let customMessage: String? = record.customMessage let infoMessageUserInfoSerialized: Data? = record.infoMessageUserInfo - let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try SDSDeserialization.optionalUnarchive(infoMessageUserInfoSerialized, name: "infoMessageUserInfo") + let infoMessageUserInfo: [InfoMessageUserInfoKey: AnyObject]? = try infoMessageUserInfoSerialized.map({ try SDSDeserialization.unarchivedInfoDictionary(from: $0) }) guard let messageType: TSInfoMessageType = record.messageType else { throw SDSError.missingRequiredField() } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let serverGuid: String? = record.serverGuid let unregisteredAddressSerialized: Data? = record.unregisteredAddress - let unregisteredAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(unregisteredAddressSerialized, name: "unregisteredAddress") + let unregisteredAddress: SignalServiceAddress? = try unregisteredAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) return TSInfoMessage(grdbId: recordId, uniqueId: uniqueId, @@ -1854,11 +1854,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1867,18 +1867,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1889,9 +1889,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") return TSInvalidIdentityKeyErrorMessage(grdbId: recordId, @@ -1938,11 +1938,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -1951,18 +1951,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -1973,9 +1973,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") let authorId: String = try SDSDeserialization.required(record.authorId, name: "authorId") let envelopeData: Data? = SDSDeserialization.optionalData(record.envelopeData, name: "envelopeData") @@ -2026,11 +2026,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -2039,18 +2039,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -2061,9 +2061,9 @@ extension TSInteraction { } let read: Bool = try SDSDeserialization.required(record.read, name: "read") let recipientAddressSerialized: Data? = record.recipientAddress - let recipientAddress: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(recipientAddressSerialized, name: "recipientAddress") + let recipientAddress: SignalServiceAddress? = try recipientAddressSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let senderSerialized: Data? = record.sender - let sender: SignalServiceAddress? = try SDSDeserialization.optionalUnarchive(senderSerialized, name: "sender") + let sender: SignalServiceAddress? = try senderSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: SignalServiceAddress.self, from: $0) }) let wasIdentityVerified: Bool = try SDSDeserialization.required(record.wasIdentityVerified, name: "wasIdentityVerified") let messageId: String = try SDSDeserialization.required(record.messageId, name: "messageId") let preKeyBundle: Data = try SDSDeserialization.required(record.preKeyBundle, name: "preKeyBundle") @@ -2114,11 +2114,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -2127,18 +2127,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -2184,11 +2184,11 @@ extension TSInteraction { let uniqueThreadId: String = record.threadUniqueId let body: String? = record.body let bodyRangesSerialized: Data? = record.bodyRanges - let bodyRanges: MessageBodyRanges? = try SDSDeserialization.optionalUnarchive(bodyRangesSerialized, name: "bodyRanges") + let bodyRanges: MessageBodyRanges? = try bodyRangesSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageBodyRanges.self, from: $0) }) let contactShareSerialized: Data? = record.contactShare - let contactShare: OWSContact? = try SDSDeserialization.optionalUnarchive(contactShareSerialized, name: "contactShare") + let contactShare: OWSContact? = try contactShareSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSContact.self, from: $0) }) let deprecated_attachmentIdsSerialized: Data? = record.deprecated_attachmentIds - let deprecated_attachmentIds: [String]? = try SDSDeserialization.optionalUnarchive(deprecated_attachmentIdsSerialized, name: "deprecated_attachmentIds") + let deprecated_attachmentIds: [String]? = try deprecated_attachmentIdsSerialized.map({ try SDSDeserialization.unarchivedArrayOfObjects(ofClass: NSString.self, from: $0) as [String] }) guard let editState: TSEditState = record.editState else { throw SDSError.missingRequiredField() } @@ -2197,18 +2197,18 @@ extension TSInteraction { let expiresAt: UInt64 = try SDSDeserialization.required(record.expiresAt, name: "expiresAt") let expiresInSeconds: UInt32 = try SDSDeserialization.required(record.expiresInSeconds, name: "expiresInSeconds") let giftBadgeSerialized: Data? = record.giftBadge - let giftBadge: OWSGiftBadge? = try SDSDeserialization.optionalUnarchive(giftBadgeSerialized, name: "giftBadge") + let giftBadge: OWSGiftBadge? = try giftBadgeSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSGiftBadge.self, from: $0) }) let isGroupStoryReply: Bool = try SDSDeserialization.required(record.isGroupStoryReply, name: "isGroupStoryReply") let isPoll: Bool = try SDSDeserialization.required(record.isPoll, name: "isPoll") let isSmsMessageRestoredFromBackup: Bool = try SDSDeserialization.required(record.isSmsMessageRestoredFromBackup, name: "isSmsMessageRestoredFromBackup") let isViewOnceComplete: Bool = try SDSDeserialization.required(record.isViewOnceComplete, name: "isViewOnceComplete") let isViewOnceMessage: Bool = try SDSDeserialization.required(record.isViewOnceMessage, name: "isViewOnceMessage") let linkPreviewSerialized: Data? = record.linkPreview - let linkPreview: OWSLinkPreview? = try SDSDeserialization.optionalUnarchive(linkPreviewSerialized, name: "linkPreview") + let linkPreview: OWSLinkPreview? = try linkPreviewSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: OWSLinkPreview.self, from: $0) }) let messageStickerSerialized: Data? = record.messageSticker - let messageSticker: MessageSticker? = try SDSDeserialization.optionalUnarchive(messageStickerSerialized, name: "messageSticker") + let messageSticker: MessageSticker? = try messageStickerSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MessageSticker.self, from: $0) }) let quotedMessageSerialized: Data? = record.quotedMessage - let quotedMessage: TSQuotedMessage? = try SDSDeserialization.optionalUnarchive(quotedMessageSerialized, name: "quotedMessage") + let quotedMessage: TSQuotedMessage? = try quotedMessageSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSQuotedMessage.self, from: $0) }) let storedShouldStartExpireTimer: Bool = try SDSDeserialization.required(record.storedShouldStartExpireTimer, name: "storedShouldStartExpireTimer") let storyAuthorUuidString: String? = record.storyAuthorUuidString let storyReactionEmoji: String? = record.storyReactionEmoji @@ -2227,7 +2227,7 @@ extension TSInteraction { let legacyWasDelivered: Bool = try SDSDeserialization.required(record.legacyWasDelivered, name: "legacyWasDelivered") let mostRecentFailureText: String? = record.mostRecentFailureText let recipientAddressStatesSerialized: Data? = record.recipientAddressStates - let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try SDSDeserialization.optionalUnarchive(recipientAddressStatesSerialized, name: "recipientAddressStates") + let recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]? = try recipientAddressStatesSerialized.map({ try SDSDeserialization.unarchivedDictionary(ofKeyClass: SignalServiceAddress.self, objectClass: TSOutgoingMessageRecipientState.self, from: $0) }) guard let storedMessageState: TSOutgoingMessageState = record.storedMessageState else { throw SDSError.missingRequiredField() } diff --git a/SignalServiceKit/Messages/Interactions/TSInteraction.h b/SignalServiceKit/Messages/Interactions/TSInteraction.h index 0d160e7c61..c97f4ac486 100644 --- a/SignalServiceKit/Messages/Interactions/TSInteraction.h +++ b/SignalServiceKit/Messages/Interactions/TSInteraction.h @@ -35,10 +35,11 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value); #pragma mark - -@interface TSInteraction : BaseModel +@interface TSInteraction : BaseModel + (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; diff --git a/SignalServiceKit/Messages/Interactions/TSInteraction.m b/SignalServiceKit/Messages/Interactions/TSInteraction.m index 41fc09deb8..7dc646781b 100644 --- a/SignalServiceKit/Messages/Interactions/TSInteraction.m +++ b/SignalServiceKit/Messages/Interactions/TSInteraction.m @@ -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) { diff --git a/SignalServiceKit/Messages/Interactions/TSMessage.m b/SignalServiceKit/Messages/Interactions/TSMessage.m index 00391aa840..9ede810f15 100644 --- a/SignalServiceKit/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSMessage.m @@ -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; } diff --git a/SignalServiceKit/Messages/Interactions/TSOutgoingDeleteMessage.m b/SignalServiceKit/Messages/Interactions/TSOutgoingDeleteMessage.m index 6ff161dedd..92e0bc7ccc 100644 --- a/SignalServiceKit/Messages/Interactions/TSOutgoingDeleteMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSOutgoingDeleteMessage.m @@ -43,6 +43,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.h index 6861b96f5f..c1d045224e 100644 --- a/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.h @@ -65,7 +65,7 @@ typedef NS_ENUM(NSInteger, EncryptionStyle) { #pragma mark - -@interface TSOutgoingMessage : TSMessage +@interface TSOutgoingMessage : TSMessage - (instancetype)initMessageWithBuilder:(TSMessageBuilder *)messageBuilder NS_UNAVAILABLE; diff --git a/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.m index 53fe411b98..2abea3d8fb 100644 --- a/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/Messages/Interactions/TSOutgoingMessage.m @@ -166,6 +166,11 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1; // --- CODE GENERATION MARKER ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Interactions/TSOutgoingMessageRecipientState.swift b/SignalServiceKit/Messages/Interactions/TSOutgoingMessageRecipientState.swift index c3dafbc503..53d48697b8 100644 --- a/SignalServiceKit/Messages/Interactions/TSOutgoingMessageRecipientState.swift +++ b/SignalServiceKit/Messages/Interactions/TSOutgoingMessageRecipientState.swift @@ -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( + func decodeObject( of cls: DecodedObjectType.Type, forCoderKey key: TSOutgoingMessageRecipientState.CoderKeys, ) -> DecodedObjectType? { return decodeObject(of: cls, forKey: key.rawValue) } - func encode( + func encode( _ object: EncodedObjectType, forCoderKey key: TSOutgoingMessageRecipientState.CoderKeys, ) { diff --git a/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.h b/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.h index 8b7e93b566..9567ede83e 100644 --- a/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.h +++ b/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.h @@ -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 diff --git a/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.m b/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.m index f74f342f4e..a0e0436949 100644 --- a/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.m +++ b/SignalServiceKit/Messages/Interactions/TSUnreadIndicatorInteraction.m @@ -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, diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.h b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.h index 34b3a076a0..83336e8b70 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.h +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.m b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.m index e50f6955cc..bd27f8c111 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.m +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyErrorMessage.m @@ -9,11 +9,6 @@ NS_ASSUME_NONNULL_BEGIN @implementation TSInvalidIdentityKeyErrorMessage -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - return [super initWithCoder:coder]; -} - - (SignalServiceAddress *)theirSignalAddress { OWSAbstractMethod(); diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.h b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.h index bc890ff850..cf2feb6549 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.h +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m index 39a95bc099..abfe58559f 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeyReceivingErrorMessage.m @@ -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]; diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.h b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.h index e21e3f6db9..29c09de3f3 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.h +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.h @@ -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 diff --git a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.m b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.m index 73306a8576..30f1b375a4 100644 --- a/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.m +++ b/SignalServiceKit/Messages/InvalidKeyMessages/TSInvalidIdentityKeySendingErrorMessage.m @@ -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]; diff --git a/SignalServiceKit/Messages/OWSOutgoingNullMessage.m b/SignalServiceKit/Messages/OWSOutgoingNullMessage.m index 8be4112a59..55679e3cb9 100644 --- a/SignalServiceKit/Messages/OWSOutgoingNullMessage.m +++ b/SignalServiceKit/Messages/OWSOutgoingNullMessage.m @@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN transaction:transaction]; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/OWSOutgoingResendRequest.m b/SignalServiceKit/Messages/OWSOutgoingResendRequest.m index 9148142980..18924dd86b 100644 --- a/SignalServiceKit/Messages/OWSOutgoingResendRequest.m +++ b/SignalServiceKit/Messages/OWSOutgoingResendRequest.m @@ -39,6 +39,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/OWSOutgoingResendResponse.swift b/SignalServiceKit/Messages/OWSOutgoingResendResponse.swift index 93c1591a97..0d84188c05 100644 --- a/SignalServiceKit/Messages/OWSOutgoingResendResponse.swift +++ b/SignalServiceKit/Messages/OWSOutgoingResendResponse.swift @@ -8,6 +8,8 @@ import LibSignalClient @objc(OWSOutgoingResendResponse) final class OWSOutgoingResendResponse: TSOutgoingMessage { + override class var supportsSecureCoding: Bool { true } + required init?(coder: NSCoder) { self.derivedContentHint = (coder.decodeObject(of: NSNumber.self, forKey: "derivedContentHint")?.intValue).flatMap(SealedSenderContentHint.init(rawValue:)) ?? .default self.didAppendSKDM = coder.decodeObject(of: NSNumber.self, forKey: "didAppendSKDM")?.boolValue ?? false diff --git a/SignalServiceKit/Messages/OWSOutgoingResendResponseTest.swift b/SignalServiceKit/Messages/OWSOutgoingResendResponseTest.swift index 22c58d7351..2f13e4efb8 100644 --- a/SignalServiceKit/Messages/OWSOutgoingResendResponseTest.swift +++ b/SignalServiceKit/Messages/OWSOutgoingResendResponseTest.swift @@ -11,7 +11,7 @@ import XCTest final class OWSOutgoingResendResponseTest: SSKBaseTest { func testStableDecoding() throws { let serializedValue = try XCTUnwrap(Data(base64Encoded: "YnBsaXN0MDDUAQIDBAUGjY5YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QGAcIS0xNTk9QUVVbXGNpbXBzen6BgoOEhVUkbnVsbN8QIQkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSlZzb3J0SWRfEBVoYXNMZWdhY3lNZXNzYWdlU3RhdGVeaXNWb2ljZU1lc3NhZ2VdZGlkQXBwZW5kU0tETV8QEmxlZ2FjeU1lc3NhZ2VTdGF0ZV8QD2V4cGlyZVN0YXJ0ZWRBdF51bmlxdWVUaHJlYWRJZFlleHBpcmVzQXRfEBFpc0dyb3VwU3RvcnlSZXBseV8QEWlzVmlld09uY2VNZXNzYWdlXxASZGVyaXZlZENvbnRlbnRIaW50XxATcmVjZWl2ZWRBdFRpbWVzdGFtcF8QEndhc1JlbW90ZWx5RGVsZXRlZF8QEmlzVmlld09uY2VDb21wbGV0ZV8QE2hhc1N5bmNlZFRyYW5zY3JpcHRYdW5pcXVlSWRdYXR0YWNobWVudElkc18QD29yaWdpbmFsR3JvdXBJZFYkY2xhc3NfEA9NVExNb2RlbFZlcnNpb25fEBxzdG9yZWRTaG91bGRTdGFydEV4cGlyZVRpbWVyXxAUd2FzTm90Q3JlYXRlZExvY2FsbHlfEBZyZWNpcGllbnRBZGRyZXNzU3RhdGVzXxAQb3JpZ2luYWxUaHJlYWRJZF8QHG91dGdvaW5nTWVzc2FnZVNjaGVtYVZlcnNpb25fEBhvcmlnaW5hbE1lc3NhZ2VQbGFpbnRleHRfEBBncm91cE1ldGFNZXNzYWdlXxASc3RvcmVkTWVzc2FnZVN0YXRlXxAQZXhwaXJlc0luU2Vjb25kc18QEmxlZ2FjeVdhc0RlbGl2ZXJlZF1zY2hlbWFWZXJzaW9uWWVkaXRTdGF0ZVl0aW1lc3RhbXCAAoADgAOAA4ACgAKABIACgAOAA4AFgAaAA4ADgAOAB4AIgAqAF4ACgAOAA4ALgBOABYAUgAKAAoACgAOAFYACgBYQAAhfECQwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMEEQARMAAAGQPGJmAV8QJDAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwQtJSG1NUWk5TLm9iamVjdHOggAnSVldYWVgkY2xhc3Nlc1okY2xhc3NuYW1lollaV05TQXJyYXlYTlNPYmplY3RPECB3+urz/99HhHOG83cb0pwqVCiPtyC5AWNM6otXolRJutNdUhteYGJXTlMua2V5c6FfgAyhYYAQgBLTG2RlZmdoW2JhY2tpbmdVdWlkXxASYmFja2luZ1Bob25lTnVtYmVygA+ADYAA0moba2xcTlMudXVpZGJ5dGVzTxAQAAAAAAAAQACAAAAAAAAADIAO0lZXbm+ib1pWTlNVVUlE0lZXcXKiclpfECVTaWduYWxTZXJ2aWNlS2l0LlNpZ25hbFNlcnZpY2VBZGRyZXNz1Bt0HHV2d3h5VXN0YXRlW3dhc1NlbnRCeVVEgBGABYACgAPSVld7fKN8fVpfEB9UU091dGdvaW5nTWVzc2FnZVJlY2lwaWVudFN0YXRlWE1UTE1vZGVs0lZXf4CigFpcTlNEaWN0aW9uYXJ5XxAtZ2QvcnE4Ly9mUjRSemh2TjNHOUtjS2xRb2o3Y2d1UUZqVE9xTFY2SlVTYm89TxBYClYKA0FCQzIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4gMyJ44MyYAB6JAogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQARAEEwAAAZA8YmYA0lZXhoeoh4iJiouMfVpfEBlPV1NPdXRnb2luZ1Jlc2VuZFJlc3BvbnNlXxARVFNPdXRnb2luZ01lc3NhZ2VZVFNNZXNzYWdlXVRTSW50ZXJhY3Rpb25ZQmFzZU1vZGVsXxATVFNZYXBEYXRhYmFzZU9iamVjdF8QD05TS2V5ZWRBcmNoaXZlctGPkFRyb290gAEACAARABoAIwAtADIANwBSAFgAnQCkALwAywDZAO4BAAEPARkBLQFBAVYBbAGBAZYBrAG1AcMB1QHcAe4CDQIkAj0CUAJvAooCnQKyAsUC2gLoAvIC/AL+AwADAgMEAwYDCAMKAwwDDgMQAxIDFAMWAxgDGgMcAx4DIAMiAyQDJgMoAyoDLAMuAzADMgM0AzYDOAM6AzwDPgNAA0EDaANqA3MDmgOfA6oDqwOtA7IDuwPGA8kD0QPaA/0EBAQMBA4EEAQSBBQEFgQdBCkEPgRABEIERARJBFYEaQRrBHAEcwR6BH8EggSqBLMEuQTFBMcEyQTLBM0E0gTWBPgFAQUGBQkFFgVGBaEFowWsBbEFugXWBeoF9AYCBgwGIgY0BjcGPAAAAAAAAAIBAAAAAAAAAJEAAAAAAAAAAAAAAAAAAAY+")) - let resendResponse = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: OWSOutgoingResendResponse.self, from: serializedValue, requiringSecureCoding: false)) + let resendResponse = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: OWSOutgoingResendResponse.self, from: serializedValue)) XCTAssertEqual( resendResponse.originalMessagePlaintext?.base64EncodedString(), "ClYKA0FCQzIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4gMyJ44MyYAB6JAogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAQ==", diff --git a/SignalServiceKit/Messages/OWSOutgoingSenderKeyDistributionMessage.m b/SignalServiceKit/Messages/OWSOutgoingSenderKeyDistributionMessage.m index 656fcb5aa8..187255735a 100644 --- a/SignalServiceKit/Messages/OWSOutgoingSenderKeyDistributionMessage.m +++ b/SignalServiceKit/Messages/OWSOutgoingSenderKeyDistributionMessage.m @@ -37,6 +37,11 @@ return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/OWSProfileKeyMessage.m b/SignalServiceKit/Messages/OWSProfileKeyMessage.m index 56cf9d30de..7347ace2e9 100644 --- a/SignalServiceKit/Messages/OWSProfileKeyMessage.m +++ b/SignalServiceKit/Messages/OWSProfileKeyMessage.m @@ -30,6 +30,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.h b/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.h index 29832bc71c..4cfe1d0291 100644 --- a/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.h +++ b/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.h @@ -53,8 +53,6 @@ NS_ASSUME_NONNULL_BEGIN untrustedGroupId:(nullable NSData *)untrustedGroupId transaction:(DBWriteTransaction *)writeTx NS_DESIGNATED_INITIALIZER; -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - @property (assign, nonatomic, readonly) BOOL supportsReplacement; // --- CODE GENERATION MARKER diff --git a/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.m b/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.m index 662c34d711..efbf098692 100644 --- a/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.m +++ b/SignalServiceKit/Messages/OWSRecoverableDecryptionPlaceholder.m @@ -41,11 +41,6 @@ NS_ASSUME_NONNULL_BEGIN return [super initErrorMessageWithBuilder:builder]; } -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - return [super initWithCoder:coder]; -} - - (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId receivedAtTimestamp:(uint64_t)receivedAtTimestamp diff --git a/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.h b/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.h index 21ec8c101d..200f7b2fc1 100644 --- a/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.h +++ b/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.h @@ -71,8 +71,6 @@ NS_ASSUME_NONNULL_BEGIN sender:(nullable SignalServiceAddress *)sender protocolVersion:(NSUInteger)protocolVersion 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 diff --git a/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.m b/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.m index 336c94bc5a..c023aff772 100644 --- a/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.m +++ b/SignalServiceKit/Messages/OWSUnknownProtocolVersionMessage.m @@ -8,14 +8,11 @@ NS_ASSUME_NONNULL_BEGIN -NSUInteger const OWSUnknownProtocolVersionMessageSchemaVersion = 1; - @interface OWSUnknownProtocolVersionMessage () @property (nonatomic) NSUInteger protocolVersion; // If nil, the invalid message was sent by a linked device. @property (nonatomic, nullable) SignalServiceAddress *sender; -@property (nonatomic, readonly) NSUInteger unknownProtocolVersionMessageSchemaVersion; @end @@ -43,55 +40,16 @@ NSUInteger const OWSUnknownProtocolVersionMessageSchemaVersion = 1; _protocolVersion = protocolVersion; _sender = sender; - _unknownProtocolVersionMessageSchemaVersion = OWSUnknownProtocolVersionMessageSchemaVersion; } return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - [coder encodeObject:[self valueForKey:@"protocolVersion"] forKey:@"protocolVersion"]; - SignalServiceAddress *sender = self.sender; - if (sender != nil) { - [coder encodeObject:sender forKey:@"sender"]; - } - [coder encodeObject:[self valueForKey:@"unknownProtocolVersionMessageSchemaVersion"] - forKey:@"unknownProtocolVersionMessageSchemaVersion"]; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_protocolVersion = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"protocolVersion"] unsignedIntegerValue]; - self->_sender = [coder decodeObjectOfClass:[SignalServiceAddress class] forKey:@"sender"]; - self->_unknownProtocolVersionMessageSchemaVersion = - [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"unknownProtocolVersionMessageSchemaVersion"] unsignedIntegerValue]; - - if (_unknownProtocolVersionMessageSchemaVersion < 1) { - NSString *_Nullable phoneNumber = [coder decodeObjectForKey:@"senderId"]; - if (phoneNumber) { - _sender = [SignalServiceAddress legacyAddressWithServiceIdString:nil phoneNumber:phoneNumber]; - } - } - - _unknownProtocolVersionMessageSchemaVersion = OWSUnknownProtocolVersionMessageSchemaVersion; - - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; result ^= self.protocolVersion; result ^= self.sender.hash; - result ^= self.unknownProtocolVersionMessageSchemaVersion; return result; } @@ -107,9 +65,6 @@ NSUInteger const OWSUnknownProtocolVersionMessageSchemaVersion = 1; if (![NSObject isObject:self.sender equalToObject:typedOther.sender]) { return NO; } - if (self.unknownProtocolVersionMessageSchemaVersion != typedOther.unknownProtocolVersionMessageSchemaVersion) { - return NO; - } return YES; } @@ -118,7 +73,6 @@ NSUInteger const OWSUnknownProtocolVersionMessageSchemaVersion = 1; OWSUnknownProtocolVersionMessage *result = [super copyWithZone:zone]; result->_protocolVersion = self.protocolVersion; result->_sender = self.sender; - result->_unknownProtocolVersionMessageSchemaVersion = self.unknownProtocolVersionMessageSchemaVersion; return result; } diff --git a/SignalServiceKit/Messages/OutgoingGroupUpdateMessage.swift b/SignalServiceKit/Messages/OutgoingGroupUpdateMessage.swift index a21b6a0fe2..35f88e5504 100644 --- a/SignalServiceKit/Messages/OutgoingGroupUpdateMessage.swift +++ b/SignalServiceKit/Messages/OutgoingGroupUpdateMessage.swift @@ -8,6 +8,8 @@ import LibSignalClient /// An outgoing group v2 update. final class OutgoingGroupUpdateMessage: TSOutgoingMessage { + override class var supportsSecureCoding: Bool { true } + required init?(coder: NSCoder) { self.isDeletingAccount = coder.decodeObject(of: NSNumber.self, forKey: "isDeletingAccount")?.boolValue ?? false self.isUpdateUrgent = coder.decodeObject(of: NSNumber.self, forKey: "isUpdateUrgent")?.boolValue ?? false diff --git a/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.h b/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.h index 0149e43527..38969da466 100644 --- a/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.h +++ b/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.h @@ -22,9 +22,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initIncomingMessageWithBuilder:(TSIncomingMessageBuilder *)messageBuilder NS_UNAVAILABLE; -// [Mantle] TODO: Don't conform to NSCoding. -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - - (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId receivedAtTimestamp:(uint64_t)receivedAtTimestamp diff --git a/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.m b/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.m index 3325f9f2aa..57fcc3ecd3 100644 --- a/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSIncomingArchivedPaymentMessage.m @@ -27,26 +27,6 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - TSArchivedPaymentInfo *archivedPaymentInfo = self.archivedPaymentInfo; - if (archivedPaymentInfo != nil) { - [coder encodeObject:archivedPaymentInfo forKey:@"archivedPaymentInfo"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_archivedPaymentInfo = [coder decodeObjectOfClass:[TSArchivedPaymentInfo class] - forKey:@"archivedPaymentInfo"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; diff --git a/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.h b/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.h index 8017e4e47d..3832ddfa2d 100644 --- a/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.h +++ b/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.h @@ -22,9 +22,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initIncomingMessageWithBuilder:(TSIncomingMessageBuilder *)messageBuilder NS_UNAVAILABLE; -// [Mantle] TODO: Don't conform to NSCoding. -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - - (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId receivedAtTimestamp:(uint64_t)receivedAtTimestamp diff --git a/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.m b/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.m index 35df52e2f9..d2511e921f 100644 --- a/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSIncomingPaymentMessage.m @@ -27,36 +27,6 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - NSData *paymentCancellation = self.paymentCancellation; - if (paymentCancellation != nil) { - [coder encodeObject:paymentCancellation forKey:@"paymentCancellation"]; - } - TSPaymentNotification *paymentNotification = self.paymentNotification; - if (paymentNotification != nil) { - [coder encodeObject:paymentNotification forKey:@"paymentNotification"]; - } - NSData *paymentRequest = self.paymentRequest; - if (paymentRequest != nil) { - [coder encodeObject:paymentRequest forKey:@"paymentRequest"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_paymentCancellation = [coder decodeObjectOfClass:[NSData class] forKey:@"paymentCancellation"]; - self->_paymentNotification = [coder decodeObjectOfClass:[TSPaymentNotification class] - forKey:@"paymentNotification"]; - self->_paymentRequest = [coder decodeObjectOfClass:[NSData class] forKey:@"paymentRequest"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; diff --git a/SignalServiceKit/Messages/Payments/OWSOutgoingArchivedPaymentMessage.m b/SignalServiceKit/Messages/Payments/OWSOutgoingArchivedPaymentMessage.m index f04a0749c6..21de172555 100644 --- a/SignalServiceKit/Messages/Payments/OWSOutgoingArchivedPaymentMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSOutgoingArchivedPaymentMessage.m @@ -30,6 +30,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Payments/OWSOutgoingPaymentMessage.m b/SignalServiceKit/Messages/Payments/OWSOutgoingPaymentMessage.m index 2906956d13..cba5e47b96 100644 --- a/SignalServiceKit/Messages/Payments/OWSOutgoingPaymentMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSOutgoingPaymentMessage.m @@ -32,6 +32,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestFinishedMessage.m b/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestFinishedMessage.m index aec43a5da5..3edf5f2f09 100644 --- a/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestFinishedMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestFinishedMessage.m @@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSPaymentActivationRequestFinishedMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (instancetype)initWithThread:(TSThread *)thread transaction:(DBReadTransaction *)transaction { TSOutgoingMessageBuilder *messageBuilder = [TSOutgoingMessageBuilder outgoingMessageBuilderWithThread:thread]; diff --git a/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestMessage.m b/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestMessage.m index 6e11183aa1..e0ae3942e2 100644 --- a/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestMessage.m +++ b/SignalServiceKit/Messages/Payments/OWSPaymentActivationRequestMessage.m @@ -10,6 +10,11 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSPaymentActivationRequestMessage ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (instancetype)initWithThread:(TSThread *)thread transaction:(DBReadTransaction *)transaction { TSOutgoingMessageBuilder *messageBuilder = [TSOutgoingMessageBuilder outgoingMessageBuilderWithThread:thread]; diff --git a/SignalServiceKit/Messages/Reactions/OWSOutgoingReactionMessage.m b/SignalServiceKit/Messages/Reactions/OWSOutgoingReactionMessage.m index b42f7bf16c..b469a2848c 100644 --- a/SignalServiceKit/Messages/Reactions/OWSOutgoingReactionMessage.m +++ b/SignalServiceKit/Messages/Reactions/OWSOutgoingReactionMessage.m @@ -40,6 +40,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; diff --git a/SignalServiceKit/Messages/Stickers/InstalledSticker+SDS.swift b/SignalServiceKit/Messages/Stickers/InstalledSticker+SDS.swift index 7c1759f1c1..d932459a51 100644 --- a/SignalServiceKit/Messages/Stickers/InstalledSticker+SDS.swift +++ b/SignalServiceKit/Messages/Stickers/InstalledSticker+SDS.swift @@ -102,7 +102,7 @@ extension InstalledSticker { let contentType: String? = record.contentType let emojiString: String? = record.emojiString let infoSerialized: Data = record.info - let info: StickerInfo = try SDSDeserialization.unarchive(infoSerialized, name: "info") + let info: StickerInfo = try SDSDeserialization.unarchivedObject(ofClass: StickerInfo.self, from: infoSerialized) return InstalledSticker(grdbId: recordId, uniqueId: uniqueId, diff --git a/SignalServiceKit/Messages/Stickers/MessageSticker.swift b/SignalServiceKit/Messages/Stickers/MessageSticker.swift index e2b07d65df..771055b410 100644 --- a/SignalServiceKit/Messages/Stickers/MessageSticker.swift +++ b/SignalServiceKit/Messages/Stickers/MessageSticker.swift @@ -39,7 +39,9 @@ public class MessageStickerDraft { // MARK: - MessageSticker @objc -public final class MessageSticker: NSObject, NSCoding, NSCopying { +public final class MessageSticker: NSObject, NSSecureCoding, NSCopying { + public static var supportsSecureCoding: Bool { true } + public init?(coder: NSCoder) { self.emoji = coder.decodeObject(of: NSString.self, forKey: "emoji") as String? self.info = coder.decodeObject(of: StickerInfo.self, forKey: "info") ?? .defaultValue diff --git a/SignalServiceKit/Messages/Stickers/StickerInfo.h b/SignalServiceKit/Messages/Stickers/StickerInfo.h index ecdd80a7d2..3481cb7d1c 100644 --- a/SignalServiceKit/Messages/Stickers/StickerInfo.h +++ b/SignalServiceKit/Messages/Stickers/StickerInfo.h @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN @class StickerPackInfo; -@interface StickerInfo : NSObject +@interface StickerInfo : NSObject @property (nonatomic, readonly) NSData *packId; @property (nonatomic, readonly) NSData *packKey; diff --git a/SignalServiceKit/Messages/Stickers/StickerInfo.m b/SignalServiceKit/Messages/Stickers/StickerInfo.m index 9e463b66e5..56a802ca4b 100644 --- a/SignalServiceKit/Messages/Stickers/StickerInfo.m +++ b/SignalServiceKit/Messages/Stickers/StickerInfo.m @@ -27,6 +27,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { NSData *packId = self.packId; diff --git a/SignalServiceKit/Messages/Stickers/StickerPack+SDS.swift b/SignalServiceKit/Messages/Stickers/StickerPack+SDS.swift index ee22ec9df3..3985e0e2dc 100644 --- a/SignalServiceKit/Messages/Stickers/StickerPack+SDS.swift +++ b/SignalServiceKit/Messages/Stickers/StickerPack+SDS.swift @@ -113,14 +113,14 @@ extension StickerPack { let uniqueId: String = record.uniqueId let author: String? = record.author let coverSerialized: Data = record.cover - let cover: StickerPackItem = try SDSDeserialization.unarchive(coverSerialized, name: "cover") + let cover: StickerPackItem = try SDSDeserialization.unarchivedObject(ofClass: StickerPackItem.self, from: coverSerialized) let dateCreatedInterval: Double = record.dateCreated let dateCreated: Date = SDSDeserialization.requiredDoubleAsDate(dateCreatedInterval, name: "dateCreated") let infoSerialized: Data = record.info - let info: StickerPackInfo = try SDSDeserialization.unarchive(infoSerialized, name: "info") + let info: StickerPackInfo = try SDSDeserialization.unarchivedObject(ofClass: StickerPackInfo.self, from: infoSerialized) let isInstalled: Bool = record.isInstalled let itemsSerialized: Data = record.items - let items: [StickerPackItem] = try SDSDeserialization.unarchive(itemsSerialized, name: "items") + let items: [StickerPackItem] = try SDSDeserialization.unarchivedArrayOfObjects(ofClass: StickerPackItem.self, from: itemsSerialized) let title: String? = record.title return StickerPack(grdbId: recordId, diff --git a/SignalServiceKit/Messages/Stickers/StickerPack.h b/SignalServiceKit/Messages/Stickers/StickerPack.h index c250cefff1..6682e2ee42 100644 --- a/SignalServiceKit/Messages/Stickers/StickerPack.h +++ b/SignalServiceKit/Messages/Stickers/StickerPack.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN @class DBWriteTransaction; @class StickerPack; -@interface StickerPackItem : NSObject +@interface StickerPackItem : NSObject @property (nonatomic, readonly) UInt32 stickerId; @property (nonatomic, readonly) NSString *emojiString; diff --git a/SignalServiceKit/Messages/Stickers/StickerPack.m b/SignalServiceKit/Messages/Stickers/StickerPack.m index f0a4b03ae5..d3690c78b7 100644 --- a/SignalServiceKit/Messages/Stickers/StickerPack.m +++ b/SignalServiceKit/Messages/Stickers/StickerPack.m @@ -29,6 +29,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { NSString *contentType = self.contentType; diff --git a/SignalServiceKit/Messages/Stickers/StickerPackInfo.swift b/SignalServiceKit/Messages/Stickers/StickerPackInfo.swift index d2151f275b..bdede57f75 100644 --- a/SignalServiceKit/Messages/Stickers/StickerPackInfo.swift +++ b/SignalServiceKit/Messages/Stickers/StickerPackInfo.swift @@ -6,7 +6,9 @@ import Foundation @objc(StickerPackInfo) -public final class StickerPackInfo: NSObject, NSCoding, NSCopying { +public final class StickerPackInfo: NSObject, NSSecureCoding, NSCopying { + public static var supportsSecureCoding: Bool { true } + public init?(coder: NSCoder) { self.packId = coder.decodeObject(of: NSData.self, forKey: "packId") as Data? self.packKey = coder.decodeObject(of: NSData.self, forKey: "packKey") as Data? diff --git a/SignalServiceKit/Messages/Stories/OutgoingStoryMessage.swift b/SignalServiceKit/Messages/Stories/OutgoingStoryMessage.swift index 882d356ceb..12d8d470f0 100644 --- a/SignalServiceKit/Messages/Stories/OutgoingStoryMessage.swift +++ b/SignalServiceKit/Messages/Stories/OutgoingStoryMessage.swift @@ -7,6 +7,8 @@ import Foundation import LibSignalClient public class OutgoingStoryMessage: TSOutgoingMessage { + override public class var supportsSecureCoding: Bool { true } + public required init?(coder: NSCoder) { self._storyMessageRowId = coder.decodeObject(of: NSNumber.self, forKey: "_storyMessageRowId") self.isPrivateStorySend = coder.decodeObject(of: NSNumber.self, forKey: "isPrivateStorySend") diff --git a/SignalServiceKit/Messages/Stories/OutgoingStorySentMessageTranscript.swift b/SignalServiceKit/Messages/Stories/OutgoingStorySentMessageTranscript.swift index 4771a10fbc..5006f6e4b2 100644 --- a/SignalServiceKit/Messages/Stories/OutgoingStorySentMessageTranscript.swift +++ b/SignalServiceKit/Messages/Stories/OutgoingStorySentMessageTranscript.swift @@ -7,6 +7,8 @@ import Foundation public import LibSignalClient public class OutgoingStorySentMessageTranscript: OWSOutgoingSyncMessage { + override public class var supportsSecureCoding: Bool { true } + public required init?(coder: NSCoder) { self.isRecipientUpdate = coder.decodeObject(of: NSNumber.self, forKey: "isRecipientUpdate") self.storyEncodedRecipientStates = coder.decodeObject(of: NSData.self, forKey: "storyEncodedRecipientStates") as Data? diff --git a/SignalServiceKit/Messages/TypingIndicatorMessage.swift b/SignalServiceKit/Messages/TypingIndicatorMessage.swift index 88e61efa34..f4c24b7cb9 100644 --- a/SignalServiceKit/Messages/TypingIndicatorMessage.swift +++ b/SignalServiceKit/Messages/TypingIndicatorMessage.swift @@ -13,6 +13,8 @@ public enum TypingIndicatorAction: Int { @objc(OWSTypingIndicatorMessage) public final class TypingIndicatorMessage: TSOutgoingMessage { + override public class var supportsSecureCoding: Bool { true } + public required init?(coder: NSCoder) { self.action = (coder.decodeObject(of: NSNumber.self, forKey: "action")?.intValue).flatMap(TypingIndicatorAction.init(rawValue:)) ?? .started super.init(coder: coder) diff --git a/SignalServiceKit/Payments/TSPaymentModel+SDS.swift b/SignalServiceKit/Payments/TSPaymentModel+SDS.swift index 281b01119f..b525d6fc9e 100644 --- a/SignalServiceKit/Payments/TSPaymentModel+SDS.swift +++ b/SignalServiceKit/Payments/TSPaymentModel+SDS.swift @@ -141,9 +141,9 @@ extension TSPaymentModel { let mcTransactionData: Data? = SDSDeserialization.optionalData(record.mcTransactionData, name: "mcTransactionData") let memoMessage: String? = record.memoMessage let mobileCoinSerialized: Data? = record.mobileCoin - let mobileCoin: MobileCoinPayment? = try SDSDeserialization.optionalUnarchive(mobileCoinSerialized, name: "mobileCoin") + let mobileCoin: MobileCoinPayment? = try mobileCoinSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: MobileCoinPayment.self, from: $0) }) let paymentAmountSerialized: Data? = record.paymentAmount - let paymentAmount: TSPaymentAmount? = try SDSDeserialization.optionalUnarchive(paymentAmountSerialized, name: "paymentAmount") + let paymentAmount: TSPaymentAmount? = try paymentAmountSerialized.map({ try SDSDeserialization.unarchivedObject(ofClass: TSPaymentAmount.self, from: $0) }) guard let paymentFailure: TSPaymentFailure = record.paymentFailure else { throw SDSError.missingRequiredField() } diff --git a/SignalServiceKit/Payments/TSPaymentModel.h b/SignalServiceKit/Payments/TSPaymentModel.h index 741c3a9eee..bcb2160f8c 100644 --- a/SignalServiceKit/Payments/TSPaymentModel.h +++ b/SignalServiceKit/Payments/TSPaymentModel.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN // without an associated interaction. // * Interactions might be deleted, but we need to maintain records of // all payments. -@interface TSPaymentModel : BaseModel +@interface TSPaymentModel : BaseModel // Incoming, outgoing, etc. // @@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)new NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE; - (instancetype)initWithUniqueId:(NSString *)uniqueId NS_UNAVAILABLE; - (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId NS_UNAVAILABLE; @@ -155,7 +155,7 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:addressUuidString:c #pragma mark - -@interface MobileCoinPayment : NSObject +@interface MobileCoinPayment : NSObject // This property is only used for transfer in/out flows. @property (nonatomic, readonly, nullable) NSData *recipientPublicAddressData; diff --git a/SignalServiceKit/Payments/TSPaymentModel.m b/SignalServiceKit/Payments/TSPaymentModel.m index de43c84814..a9501b80f0 100644 --- a/SignalServiceKit/Payments/TSPaymentModel.m +++ b/SignalServiceKit/Payments/TSPaymentModel.m @@ -93,77 +93,6 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [self encodeIdsWithCoder:coder]; - NSString *addressUuidString = self.addressUuidString; - if (addressUuidString != nil) { - [coder encodeObject:addressUuidString forKey:@"addressUuidString"]; - } - [coder encodeObject:[self valueForKey:@"createdTimestamp"] forKey:@"createdTimestamp"]; - NSString *interactionUniqueId = self.interactionUniqueId; - if (interactionUniqueId != nil) { - [coder encodeObject:interactionUniqueId forKey:@"interactionUniqueId"]; - } - [coder encodeObject:[self valueForKey:@"isUnread"] forKey:@"isUnread"]; - [coder encodeObject:[self valueForKey:@"mcLedgerBlockIndex"] forKey:@"mcLedgerBlockIndex"]; - NSData *mcReceiptData = self.mcReceiptData; - if (mcReceiptData != nil) { - [coder encodeObject:mcReceiptData forKey:@"mcReceiptData"]; - } - NSData *mcTransactionData = self.mcTransactionData; - if (mcTransactionData != nil) { - [coder encodeObject:mcTransactionData forKey:@"mcTransactionData"]; - } - NSString *memoMessage = self.memoMessage; - if (memoMessage != nil) { - [coder encodeObject:memoMessage forKey:@"memoMessage"]; - } - MobileCoinPayment *mobileCoin = self.mobileCoin; - if (mobileCoin != nil) { - [coder encodeObject:mobileCoin forKey:@"mobileCoin"]; - } - TSPaymentAmount *paymentAmount = self.paymentAmount; - if (paymentAmount != nil) { - [coder encodeObject:paymentAmount forKey:@"paymentAmount"]; - } - [coder encodeObject:[self valueForKey:@"paymentFailure"] forKey:@"paymentFailure"]; - [coder encodeObject:[self valueForKey:@"paymentState"] forKey:@"paymentState"]; - [coder encodeObject:[self valueForKey:@"paymentType"] forKey:@"paymentType"]; - NSString *requestUuidString = self.requestUuidString; - if (requestUuidString != nil) { - [coder encodeObject:requestUuidString forKey:@"requestUuidString"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_addressUuidString = [coder decodeObjectOfClass:[NSString class] forKey:@"addressUuidString"]; - self->_createdTimestamp = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"createdTimestamp"] unsignedLongLongValue]; - self->_interactionUniqueId = [coder decodeObjectOfClass:[NSString class] forKey:@"interactionUniqueId"]; - self->_isUnread = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"isUnread"] boolValue]; - self->_mcLedgerBlockIndex = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"mcLedgerBlockIndex"] unsignedLongLongValue]; - self->_mcReceiptData = [coder decodeObjectOfClass:[NSData class] forKey:@"mcReceiptData"]; - self->_mcTransactionData = [coder decodeObjectOfClass:[NSData class] forKey:@"mcTransactionData"]; - self->_memoMessage = [coder decodeObjectOfClass:[NSString class] forKey:@"memoMessage"]; - self->_mobileCoin = [coder decodeObjectOfClass:[MobileCoinPayment class] forKey:@"mobileCoin"]; - self->_paymentAmount = [coder decodeObjectOfClass:[TSPaymentAmount class] forKey:@"paymentAmount"]; - self->_paymentFailure = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"paymentFailure"] unsignedIntegerValue]; - self->_paymentState = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"paymentState"] unsignedIntegerValue]; - self->_paymentType = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"paymentType"] unsignedIntegerValue]; - self->_requestUuidString = [coder decodeObjectOfClass:[NSString class] forKey:@"requestUuidString"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; @@ -481,6 +410,11 @@ NS_ASSUME_NONNULL_BEGIN return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { TSPaymentAmount *feeAmount = self.feeAmount; diff --git a/SignalServiceKit/Payments/TSPaymentModels.h b/SignalServiceKit/Payments/TSPaymentModels.h index 6a26f82ffe..f6cfed9c56 100644 --- a/SignalServiceKit/Payments/TSPaymentModels.h +++ b/SignalServiceKit/Payments/TSPaymentModels.h @@ -94,7 +94,7 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value); #pragma mark - -@interface TSPaymentAmount : NSObject +@interface TSPaymentAmount : NSObject @property (nonatomic, readonly) TSPaymentCurrency currency; @property (nonatomic, readonly) uint64_t picoMob; @@ -105,7 +105,7 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value); #pragma mark - -@interface TSPaymentAddress : NSObject +@interface TSPaymentAddress : NSObject @property (nonatomic, readonly) TSPaymentCurrency currency; @property (nonatomic, readonly) NSData *mobileCoinPublicAddressData; @@ -117,7 +117,7 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value); #pragma mark - -@interface TSPaymentNotification : NSObject +@interface TSPaymentNotification : NSObject @property (nonatomic, readonly, nullable) NSString *memoMessage; @property (nonatomic, readonly) NSData *mcReceiptData; @@ -128,7 +128,7 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value); #pragma mark - -@interface TSArchivedPaymentInfo : NSObject +@interface TSArchivedPaymentInfo : NSObject @property (nonatomic, readonly, nullable) NSString *amount; @property (nonatomic, readonly, nullable) NSString *fee; diff --git a/SignalServiceKit/Payments/TSPaymentModels.m b/SignalServiceKit/Payments/TSPaymentModels.m index 25dbaf890b..6ad0fafdfc 100644 --- a/SignalServiceKit/Payments/TSPaymentModels.m +++ b/SignalServiceKit/Payments/TSPaymentModels.m @@ -122,6 +122,11 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value) return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:[self valueForKey:@"currency"] forKey:@"currency"]; @@ -194,28 +199,6 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value) return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeObject:[self valueForKey:@"currency"] forKey:@"currency"]; - NSData *mobileCoinPublicAddressData = self.mobileCoinPublicAddressData; - if (mobileCoinPublicAddressData != nil) { - [coder encodeObject:mobileCoinPublicAddressData forKey:@"mobileCoinPublicAddressData"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super init]; - if (!self) { - return self; - } - self->_currency = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"currency"] unsignedIntegerValue]; - self->_mobileCoinPublicAddressData = [coder decodeObjectOfClass:[NSData class] - forKey:@"mobileCoinPublicAddressData"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = 0; @@ -269,6 +252,11 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value) return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { NSData *mcReceiptData = self.mcReceiptData; @@ -344,6 +332,11 @@ NSString *NSStringFromTSPaymentFailure(TSPaymentFailure value) return self; } ++ (BOOL)supportsSecureCoding +{ + return YES; +} + - (void)encodeWithCoder:(NSCoder *)coder { NSString *amount = self.amount; diff --git a/SignalServiceKit/Profiles/OWSProfileManager.swift b/SignalServiceKit/Profiles/OWSProfileManager.swift index f7f520e9d7..ae565d5757 100644 --- a/SignalServiceKit/Profiles/OWSProfileManager.swift +++ b/SignalServiceKit/Profiles/OWSProfileManager.swift @@ -1433,7 +1433,7 @@ public class PendingProfileUpdate: NSObject, NSSecureCoding { return avatarData.map { $0?.nilIfEmpty } } - // MARK: - NSCoding + // MARK: - NSSecureCoding public class var supportsSecureCoding: Bool { true } diff --git a/SignalServiceKit/Storage/Database/SDSCodableModel/SDSCodableModel+SDSSerialization.swift b/SignalServiceKit/Storage/Database/SDSCodableModel/SDSCodableModel+SDSSerialization.swift index 174f791216..7d48791405 100644 --- a/SignalServiceKit/Storage/Database/SDSCodableModel/SDSCodableModel+SDSSerialization.swift +++ b/SignalServiceKit/Storage/Database/SDSCodableModel/SDSCodableModel+SDSSerialization.swift @@ -28,7 +28,14 @@ struct SDSCodableModelLegacySerializer: SDSSerializer { /// /// For use with complex properties that are stored in a single BLOB column. func deserializeLegacySDSData(_ encodedValue: Data, ofClass cls: T.Type) throws -> T { - guard let result = try? NSKeyedUnarchiver.unarchivedObject(ofClass: cls, from: encodedValue) else { + let result: T? + do { + result = try NSKeyedUnarchiver.unarchivedObject(ofClass: cls, from: encodedValue) + } catch { + Logger.warn("couldn't decode legacy data: \(error)") + throw SDSError.invalidValue() + } + guard let result else { throw SDSError.invalidValue() } return result diff --git a/SignalServiceKit/Storage/Database/SDSDeserialization.swift b/SignalServiceKit/Storage/Database/SDSDeserialization.swift index 1e2aed60d7..41eaef9de0 100644 --- a/SignalServiceKit/Storage/Database/SDSDeserialization.swift +++ b/SignalServiceKit/Storage/Database/SDSDeserialization.swift @@ -60,34 +60,48 @@ public class SDSDeserialization { // MARK: - Blob - public class func optionalUnarchive(_ encoded: Data?, name: String) throws -> T? { - guard let encoded else { - return nil + public class func unarchivedObject( + ofClass cls: T.Type, + from encodedValue: Data, + ) throws -> T { + let decodedValue = try NSKeyedUnarchiver.unarchivedObject(ofClass: cls, from: encodedValue) + guard let decodedValue else { + throw SDSError.invalidValue() } - return try unarchive(encoded, name: name) + return decodedValue } - public class func unarchive( - _ encoded: Data?, - name: String, - _ file: StaticString = #file, - _ function: StaticString = #function, - _ line: UInt = #line, - ) throws -> T { - guard let encoded else { - owsFailDebug("Missing required field: \(name).") - throw SDSError.missingRequiredField(file, function, line) + public class func unarchivedArrayOfObjects( + ofClass cls: T.Type, + from encodedValue: Data, + ) throws -> [T] { + let decodedValue = try NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: cls, from: encodedValue) + guard let decodedValue else { + throw SDSError.invalidValue() } + return decodedValue + } - do { - guard let decoded = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(encoded) as? T else { - owsFailDebug("Invalid value: \(name).") - throw SDSError.invalidValue(file, function, line) - } - return decoded - } catch { - owsFailDebug("Read failed[\(name)]: \(error).") - throw SDSError.invalidValue(file, function, line) + public class func unarchivedDictionary( + ofKeyClass keyClass: K.Type, + objectClass: V.Type, + from encodedValue: Data, + ) throws -> [K: V] { + let decodedValue = try NSKeyedUnarchiver.unarchivedDictionary(ofKeyClass: keyClass, objectClass: objectClass, from: encodedValue) + guard let decodedValue else { + throw SDSError.invalidValue() } + return decodedValue + } + + public class func unarchivedInfoDictionary(from encodedValue: Data) throws -> [InfoMessageUserInfoKey: AnyObject] { + let decodedValue = try NSKeyedUnarchiver.unarchivedObject( + ofClasses: [NSDictionary.self, NSString.self] + TSInfoMessage.infoMessageUserInfoObjectClasses(), + from: encodedValue, + ) as? [InfoMessageUserInfoKey: AnyObject] + guard let decodedValue else { + throw SDSError.invalidValue() + } + return decodedValue } } diff --git a/SignalServiceKit/Storage/Database/SDSSerializable.swift b/SignalServiceKit/Storage/Database/SDSSerializable.swift index 7bb974322c..adf38e04dc 100644 --- a/SignalServiceKit/Storage/Database/SDSSerializable.swift +++ b/SignalServiceKit/Storage/Database/SDSSerializable.swift @@ -48,20 +48,28 @@ public extension SDSSerializer { // MARK: - Blob - func optionalArchive(_ value: Any?) -> Data? { + func optionalArchive(_ value: T?) -> Data? { guard let value else { return nil } return requiredArchive(value) } + func optionalArchive(_ value: [SignalServiceAddress: TSOutgoingMessageRecipientState]?) -> Data? { + return optionalArchive(value as NSDictionary?) + } + + func optionalArchive(_ value: [InfoMessageUserInfoKey: Any]?) -> Data? { + return optionalArchive(value as NSDictionary?) + } + /// Avoid the cost of actually archiving empty string arrays that are /// declared optional (e.g. TSInteraction.attachmentIds) func optionalArchive(_ value: [String]?) -> Data? { guard let value, !value.isEmpty else { return nil } - return requiredArchive(value) + return requiredArchive(value as [NSString] as NSArray) } /// Avoide the cost of actually archiving empty message body range objects. @@ -72,7 +80,11 @@ public extension SDSSerializer { return requiredArchive(value) } - func requiredArchive(_ value: Any) -> Data { - return try! NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: false) + func requiredArchive(_ value: [T]) -> Data { + return requiredArchive(value as NSArray) + } + + func requiredArchive(_ value: T) -> Data { + return try! NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true) } } diff --git a/SignalServiceKit/Threads/TSContactThread.h b/SignalServiceKit/Threads/TSContactThread.h index f5211e9088..952253548d 100644 --- a/SignalServiceKit/Threads/TSContactThread.h +++ b/SignalServiceKit/Threads/TSContactThread.h @@ -22,8 +22,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithUniqueId:(NSString *)uniqueId NS_UNAVAILABLE; -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - - (instancetype)initWithContactUUID:(nullable NSString *)contactUUID contactPhoneNumber:(nullable NSString *)contactPhoneNumber NS_DESIGNATED_INITIALIZER; @@ -100,9 +98,6 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:conversationColorNa + (nullable SignalServiceAddress *)contactAddressFromThreadId:(NSString *)threadId transaction:(DBReadTransaction *)transaction; -// This is only ever used from migration from a pre-UUID world to a UUID world -+ (nullable NSString *)legacyContactPhoneNumberFromThreadId:(NSString *)threadId; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/Threads/TSContactThread.m b/SignalServiceKit/Threads/TSContactThread.m index 0ef540d7e2..66f979b669 100644 --- a/SignalServiceKit/Threads/TSContactThread.m +++ b/SignalServiceKit/Threads/TSContactThread.m @@ -8,15 +8,6 @@ NS_ASSUME_NONNULL_BEGIN -NSString *const TSContactThreadLegacyPrefix = @"c"; -NSUInteger const TSContactThreadSchemaVersion = 1; - -@interface TSContactThread () - -@property (nonatomic, readonly) NSUInteger contactThreadSchemaVersion; - -@end - #pragma mark - @implementation TSContactThread @@ -97,49 +88,10 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO // --- CODE GENERATION MARKER -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - NSString *contactPhoneNumber = self.contactPhoneNumber; - if (contactPhoneNumber != nil) { - [coder encodeObject:contactPhoneNumber forKey:@"contactPhoneNumber"]; - } - [coder encodeObject:[self valueForKey:@"contactThreadSchemaVersion"] forKey:@"contactThreadSchemaVersion"]; - NSString *contactUUID = self.contactUUID; - if (contactUUID != nil) { - [coder encodeObject:contactUUID forKey:@"contactUUID"]; - } - [coder encodeObject:[self valueForKey:@"hasDismissedOffers"] forKey:@"hasDismissedOffers"]; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_contactPhoneNumber = [coder decodeObjectOfClass:[NSString class] forKey:@"contactPhoneNumber"]; - self->_contactThreadSchemaVersion = - [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"contactThreadSchemaVersion"] unsignedIntegerValue]; - self->_contactUUID = [coder decodeObjectOfClass:[NSString class] forKey:@"contactUUID"]; - self->_hasDismissedOffers = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] - forKey:@"hasDismissedOffers"] boolValue]; - - // Migrate legacy threads to store phone number and UUID - if (_contactThreadSchemaVersion < 1) { - _contactPhoneNumber = [[self class] legacyContactPhoneNumberFromThreadId:self.uniqueId]; - } - _contactThreadSchemaVersion = TSContactThreadSchemaVersion; - - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; result ^= self.contactPhoneNumber.hash; - result ^= self.contactThreadSchemaVersion; result ^= self.contactUUID.hash; result ^= self.hasDismissedOffers; return result; @@ -154,9 +106,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO if (![NSObject isObject:self.contactPhoneNumber equalToObject:typedOther.contactPhoneNumber]) { return NO; } - if (self.contactThreadSchemaVersion != typedOther.contactThreadSchemaVersion) { - return NO; - } if (![NSObject isObject:self.contactUUID equalToObject:typedOther.contactUUID]) { return NO; } @@ -170,7 +119,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO { TSContactThread *result = [super copyWithZone:zone]; result->_contactPhoneNumber = self.contactPhoneNumber; - result->_contactThreadSchemaVersion = self.contactThreadSchemaVersion; result->_contactUUID = self.contactUUID; result->_hasDismissedOffers = self.hasDismissedOffers; return result; @@ -184,7 +132,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO if (self = [super initWithUniqueId:uniqueId]) { _contactUUID = [contactUUID copy]; _contactPhoneNumber = [contactPhoneNumber copy]; - _contactThreadSchemaVersion = TSContactThreadSchemaVersion; } return self; @@ -245,16 +192,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO return self.contactAddress.isLocalAddress; } -- (NSString *)colorSeed -{ - NSString *_Nullable phoneNumber = self.contactAddress.phoneNumber; - if (!phoneNumber) { - phoneNumber = [[self class] legacyContactPhoneNumberFromThreadId:self.uniqueId]; - } - - return phoneNumber ?: self.uniqueId; -} - - (BOOL)hasSafetyNumbers { return [OWSIdentityManagerObjCBridge identityKeyForAddress:self.contactAddress] != nil; @@ -266,15 +203,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO return [TSContactThread anyFetchContactThreadWithUniqueId:threadId transaction:transaction].contactAddress; } -+ (nullable NSString *)legacyContactPhoneNumberFromThreadId:(NSString *)threadId -{ - if (![threadId hasPrefix:TSContactThreadLegacyPrefix]) { - return nil; - } - - return [threadId substringWithRange:NSMakeRange(1, threadId.length - 1)]; -} - - (void)anyDidInsertWithTransaction:(DBWriteTransaction *)transaction { [super anyDidInsertWithTransaction:transaction]; diff --git a/SignalServiceKit/Threads/TSGroupThread.h b/SignalServiceKit/Threads/TSGroupThread.h index 9b0c4ae41f..7278897b01 100644 --- a/SignalServiceKit/Threads/TSGroupThread.h +++ b/SignalServiceKit/Threads/TSGroupThread.h @@ -22,8 +22,6 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithUniqueId:(NSString *)uniqueId NS_UNAVAILABLE; -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - - (instancetype)initWithGroupModel:(TSGroupModelV2 *)groupModel NS_DESIGNATED_INITIALIZER; - (instancetype)initWithGrdbId:(int64_t)grdbId diff --git a/SignalServiceKit/Threads/TSGroupThread.m b/SignalServiceKit/Threads/TSGroupThread.m index 456066f45e..08fd823abb 100644 --- a/SignalServiceKit/Threads/TSGroupThread.m +++ b/SignalServiceKit/Threads/TSGroupThread.m @@ -78,25 +78,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO // --- CODE GENERATION MARKER -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - TSGroupModel *groupModel = self.groupModel; - if (groupModel != nil) { - [coder encodeObject:groupModel forKey:@"groupModel"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_groupModel = [coder decodeObjectOfClass:[TSGroupModel class] forKey:@"groupModel"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; diff --git a/SignalServiceKit/Threads/TSPrivateStoryThread.h b/SignalServiceKit/Threads/TSPrivateStoryThread.h index 6400230e09..6d3168f6c1 100644 --- a/SignalServiceKit/Threads/TSPrivateStoryThread.h +++ b/SignalServiceKit/Threads/TSPrivateStoryThread.h @@ -29,7 +29,6 @@ NS_ASSUME_NONNULL_BEGIN viewMode:(TSThreadStoryViewMode)viewMode NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; -- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithUniqueId:(NSString *)uniqueId NS_UNAVAILABLE; - (instancetype)initWithGrdbId:(int64_t)grdbId uniqueId:(NSString *)uniqueId diff --git a/SignalServiceKit/Threads/TSPrivateStoryThread.m b/SignalServiceKit/Threads/TSPrivateStoryThread.m index 329e718858..c7abbcb58e 100644 --- a/SignalServiceKit/Threads/TSPrivateStoryThread.m +++ b/SignalServiceKit/Threads/TSPrivateStoryThread.m @@ -22,32 +22,6 @@ return self; } -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - NSData *addresses = self.addresses; - if (addresses != nil) { - [coder encodeObject:addresses forKey:@"addresses"]; - } - [coder encodeObject:[self valueForKey:@"allowsReplies"] forKey:@"allowsReplies"]; - NSString *name = self.name; - if (name != nil) { - [coder encodeObject:name forKey:@"name"]; - } -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (!self) { - return self; - } - self->_addresses = [coder decodeObjectOfClass:[NSData class] forKey:@"addresses"]; - self->_allowsReplies = [(NSNumber *)[coder decodeObjectOfClass:[NSNumber class] forKey:@"allowsReplies"] boolValue]; - self->_name = [coder decodeObjectOfClass:[NSString class] forKey:@"name"]; - return self; -} - - (NSUInteger)hash { NSUInteger result = [super hash]; diff --git a/SignalServiceKit/Util/NSKeyedUnarchiver+SSK.swift b/SignalServiceKit/Util/NSKeyedUnarchiver+SSK.swift deleted file mode 100644 index 7ecd58fe9e..0000000000 --- a/SignalServiceKit/Util/NSKeyedUnarchiver+SSK.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright 2023 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only -// - -import Foundation - -extension NSKeyedUnarchiver { - public static func unarchivedObject( - ofClass cls: DecodedObjectType.Type, - from data: Data, - requiringSecureCoding: Bool, - ) throws -> DecodedObjectType? where DecodedObjectType: NSObject, DecodedObjectType: NSCoding { - let coder = try NSKeyedUnarchiver(forReadingFrom: data) - coder.requiresSecureCoding = requiringSecureCoding - return try coder.decodeTopLevelObject(of: cls, forKey: NSKeyedArchiveRootObjectKey) - } -} diff --git a/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift b/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift index 1a4e75768c..32cc78f2ab 100644 --- a/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift +++ b/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift @@ -36,7 +36,6 @@ final class OutgoingCallEventSyncMessageSerializationTest: SSKBaseTest { let syncMessage = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingCallEventSyncMessage.self, from: archivedObjCCallEventSyncMessage, - requiringSecureCoding: false, ) else { XCTFail("Failed to decode sync message!") @@ -86,14 +85,13 @@ final class OutgoingCallEventSyncMessageSerializationTest: SSKBaseTest { let archivedData = try NSKeyedArchiver.archivedData( withRootObject: syncMessage, - requiringSecureCoding: false, + requiringSecureCoding: true, ) guard let deserializedSyncMessage = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingCallEventSyncMessage.self, from: archivedData, - requiringSecureCoding: false, ) else { XCTFail("Got nil when unarchiving!") diff --git a/SignalServiceKit/tests/Calls/OutgoingCallLogEventSyncMessageTest.swift b/SignalServiceKit/tests/Calls/OutgoingCallLogEventSyncMessageTest.swift index fb6deee2c7..06b8a7637f 100644 --- a/SignalServiceKit/tests/Calls/OutgoingCallLogEventSyncMessageTest.swift +++ b/SignalServiceKit/tests/Calls/OutgoingCallLogEventSyncMessageTest.swift @@ -16,7 +16,6 @@ final class OutgoingCallLogEventSyncMessageTest: XCTestCase { let deserializedSyncMessageEvent = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingCallLogEventSyncMessage.CallLogEvent.self, from: archivedData, - requiringSecureCoding: false, ) else { XCTFail("Got nil while archiving!") @@ -47,14 +46,13 @@ final class OutgoingCallLogEventSyncMessageTest: XCTestCase { for syncMessageEvent in syncMessageEvents { let archivedData = try NSKeyedArchiver.archivedData( withRootObject: syncMessageEvent, - requiringSecureCoding: false, + requiringSecureCoding: true, ) guard let deserializedSyncMessageEvent = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingCallLogEventSyncMessage.CallLogEvent.self, from: archivedData, - requiringSecureCoding: false, ) else { XCTFail("Got nil when unarchiving!") diff --git a/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift b/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift index 3bb5119db7..2293c6291b 100644 --- a/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift +++ b/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift @@ -36,14 +36,13 @@ final class OutgoingGroupCallUpdateMessageSerializationTest: SSKBaseTest { let archivedData = try NSKeyedArchiver.archivedData( withRootObject: updateMessage, - requiringSecureCoding: false, + requiringSecureCoding: true, ) guard let deserializedMessage = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingGroupCallUpdateMessage.self, from: archivedData, - requiringSecureCoding: false, ) else { XCTFail("Failed to deserialize!") @@ -71,7 +70,6 @@ final class OutgoingGroupCallUpdateMessageSerializationTest: SSKBaseTest { let updateMessage = try NSKeyedUnarchiver.unarchivedObject( ofClass: OutgoingGroupCallUpdateMessage.self, from: hardcodedObjcInstanceData, - requiringSecureCoding: false, ) else { XCTFail("Failed to unarchive!") diff --git a/SignalServiceKit/tests/Curve25519/ECKeyPairTest.swift b/SignalServiceKit/tests/Curve25519/ECKeyPairTest.swift index 581ce66fa9..a02afe2cbc 100644 --- a/SignalServiceKit/tests/Curve25519/ECKeyPairTest.swift +++ b/SignalServiceKit/tests/Curve25519/ECKeyPairTest.swift @@ -24,7 +24,7 @@ final class ECKeyPairTest: XCTestCase { let keyPair = ECKeyPair(IdentityKeyPair(publicKey: privateKey.publicKey, privateKey: privateKey)) let encodedData = try NSKeyedArchiver.archivedData(withRootObject: keyPair, requiringSecureCoding: true) - let decodedKeyPair = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData, requiringSecureCoding: true)) + let decodedKeyPair = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData)) XCTAssertEqual(decodedKeyPair.identityKeyPair.privateKey.serialize(), keyPair.identityKeyPair.privateKey.serialize()) XCTAssertEqual(decodedKeyPair.identityKeyPair.publicKey, keyPair.identityKeyPair.publicKey) @@ -38,7 +38,7 @@ final class ECKeyPairTest: XCTestCase { base64Encoded: "YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGjCwwTVSRudWxs0w0ODxAREl8QFVRTRUNLZXlQYWlyUHJpdmF0ZUtleV8QFFRTRUNLZXlQYWlyUHVibGljS2V5ViRjbGFzc08QIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBTxAg/TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xWAAtIUFRYXWiRjbGFzc25hbWVYJGNsYXNzZXNZRUNLZXlQYWlyohYYWE5TT2JqZWN0AAgAEQAaACQAKQAyADcASQBMAFEAUwBXAF0AZAB8AJMAmgC9AOAA4gDnAPIA+wEFAQgAAAAAAAACAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAABEQ==", )) let decodedKeyPair = try XCTUnwrap( - NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData, requiringSecureCoding: true), + NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData), ) XCTAssertEqual(decodedKeyPair.identityKeyPair.privateKey.serialize(), keyPair.identityKeyPair.privateKey.serialize()) @@ -54,9 +54,7 @@ final class ECKeyPairTest: XCTestCase { ] for encodedValue in encodedValues { let encodedData = try XCTUnwrap(Data(base64Encoded: encodedValue)) - XCTAssertNil( - try NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData, requiringSecureCoding: true), - ) + XCTAssertThrowsError(try NSKeyedUnarchiver.unarchivedObject(ofClass: ECKeyPair.self, from: encodedData)) } } } diff --git a/SignalServiceKit/tests/Groups/GroupModelsTest.swift b/SignalServiceKit/tests/Groups/GroupModelsTest.swift index 0a3dcee5c8..e12b212905 100644 --- a/SignalServiceKit/tests/Groups/GroupModelsTest.swift +++ b/SignalServiceKit/tests/Groups/GroupModelsTest.swift @@ -137,7 +137,7 @@ class GroupModelsTest: SSKBaseTest { let encodedData = Data.data(fromHex: hexData)! - let groupModel = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: TSGroupModel.self, from: encodedData, requiringSecureCoding: false)) + let groupModel = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject(ofClass: TSGroupModel.self, from: encodedData)) XCTAssertEqual(groupModel.groupId, expectedGroupId) } @@ -174,7 +174,7 @@ class GroupModelsTest: SSKBaseTest { return try! NSKeyedArchiver.archivedData( withRootObject: model, - requiringSecureCoding: false, + requiringSecureCoding: true, ).hexadecimalString } @@ -206,7 +206,6 @@ class GroupModelsTest: SSKBaseTest { let groupModel = try XCTUnwrap(NSKeyedUnarchiver.unarchivedObject( ofClass: TSGroupModelV2.self, from: encodedData, - requiringSecureCoding: false, )) XCTAssertEqual(groupModel.groupId, expectedGroupId) diff --git a/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageRecipientStateTest.swift b/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageRecipientStateTest.swift index f4aa1516d8..a5846e2270 100644 --- a/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageRecipientStateTest.swift +++ b/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageRecipientStateTest.swift @@ -86,7 +86,6 @@ final class TSOutgoingMessageRecipientStateTest: XCTestCase { let state = try NSKeyedUnarchiver.unarchivedObject( ofClass: TSOutgoingMessageRecipientState.self, from: testCase.data, - requiringSecureCoding: false, ) guard let state else { diff --git a/SignalServiceKit/tests/Messages/LinkPreview/OWSLinkPreviewSerializationTest.swift b/SignalServiceKit/tests/Messages/LinkPreview/OWSLinkPreviewSerializationTest.swift index 72c6d75f77..737172073d 100644 --- a/SignalServiceKit/tests/Messages/LinkPreview/OWSLinkPreviewSerializationTest.swift +++ b/SignalServiceKit/tests/Messages/LinkPreview/OWSLinkPreviewSerializationTest.swift @@ -25,7 +25,7 @@ class OWSLinkPreviewSerializationTest: XCTestCase { for (idx, (constant, _, _)) in OWSLinkPreview.constants.enumerated() { let serializedArchiver = try! NSKeyedArchiver.archivedData( withRootObject: constant, - requiringSecureCoding: false, + requiringSecureCoding: true, ) print("\(Self.self) constant \(idx) keyed archiver: \(serializedArchiver.base64EncodedString())") @@ -39,7 +39,6 @@ class OWSLinkPreviewSerializationTest: XCTestCase { let deserialized = try NSKeyedUnarchiver.unarchivedObject( ofClass: OWSLinkPreview.self, from: archiverData, - requiringSecureCoding: false, )! try deserialized.validate(against: constant) } catch ValidatableModelError.failedToValidate { diff --git a/SignalServiceKit/tests/Messages/MessageSendLogTests.swift b/SignalServiceKit/tests/Messages/MessageSendLogTests.swift index a8db1a01f1..eb48417e4b 100644 --- a/SignalServiceKit/tests/Messages/MessageSendLogTests.swift +++ b/SignalServiceKit/tests/Messages/MessageSendLogTests.swift @@ -531,10 +531,6 @@ class MessageSendLogTests: SSKBaseTest { fatalError("init(coder:) has not been implemented") } - required init(dictionary dictionaryValue: [String: Any]!) throws { - fatalError("init(dictionary:) has not been implemented") - } - var _contentHint: SealedSenderContentHint = .resendable override var contentHint: SealedSenderContentHint { _contentHint } diff --git a/SignalServiceKit/tests/Messages/Quotes/OWSAttachmentInfoSerializationTest.swift b/SignalServiceKit/tests/Messages/Quotes/OWSAttachmentInfoSerializationTest.swift index d421f02740..5a943d7da5 100644 --- a/SignalServiceKit/tests/Messages/Quotes/OWSAttachmentInfoSerializationTest.swift +++ b/SignalServiceKit/tests/Messages/Quotes/OWSAttachmentInfoSerializationTest.swift @@ -25,7 +25,7 @@ class OWSAttachmentInfoSerializationTest: XCTestCase { for (idx, (constant, _)) in OWSAttachmentInfo.constants.enumerated() { let serializedArchiver = try! NSKeyedArchiver.archivedData( withRootObject: constant, - requiringSecureCoding: false, + requiringSecureCoding: true, ) print("\(Self.self) constant \(idx) keyed archiver: \(serializedArchiver.base64EncodedString())") } @@ -36,7 +36,6 @@ class OWSAttachmentInfoSerializationTest: XCTestCase { let deserialized = try NSKeyedUnarchiver.unarchivedObject( ofClass: OWSAttachmentInfo.self, from: archiverData, - requiringSecureCoding: false, )! try deserialized.validate(against: constant) } catch ValidatableModelError.failedToValidate { diff --git a/SignalServiceKit/tests/Messages/SignalServiceAddressTest.swift b/SignalServiceKit/tests/Messages/SignalServiceAddressTest.swift index 7e13849d36..bc70209910 100644 --- a/SignalServiceKit/tests/Messages/SignalServiceAddressTest.swift +++ b/SignalServiceKit/tests/Messages/SignalServiceAddressTest.swift @@ -691,7 +691,6 @@ class SignalServiceAddress2Test: SSKBaseTest { let decodedValue = try NSKeyedUnarchiver.unarchivedObject( ofClass: SignalServiceAddress.self, from: encodedValue, - requiringSecureCoding: true, )! XCTAssertEqual(decodedValue.serviceId, testCase.decodedServiceId) XCTAssertEqual(decodedValue.phoneNumber, testCase.decodedPhoneNumber) @@ -751,7 +750,6 @@ class SignalServiceAddress2Test: SSKBaseTest { let decodedValue = try NSKeyedUnarchiver.unarchivedObject( ofClass: SignalServiceAddress.self, from: Data(base64Encoded: testCase.keyedArchiverValue)!, - requiringSecureCoding: true, )! XCTAssertEqual(decodedValue.serviceId, testCase.decodedServiceId) XCTAssertEqual(decodedValue.phoneNumber, testCase.decodedPhoneNumber) diff --git a/SignalServiceKit/tests/Messages/Stickers/MessageStickerSerializationTest.swift b/SignalServiceKit/tests/Messages/Stickers/MessageStickerSerializationTest.swift index ff8601c09b..ca520cb51e 100644 --- a/SignalServiceKit/tests/Messages/Stickers/MessageStickerSerializationTest.swift +++ b/SignalServiceKit/tests/Messages/Stickers/MessageStickerSerializationTest.swift @@ -25,7 +25,7 @@ class MessageStickerSerializationTest: XCTestCase { for (idx, (constant, _)) in MessageSticker.constants.enumerated() { let serializedArchiver = try! NSKeyedArchiver.archivedData( withRootObject: constant, - requiringSecureCoding: false, + requiringSecureCoding: true, ) print("\(Self.self) constant \(idx) keyed archiver: \(serializedArchiver.base64EncodedString())") } @@ -36,7 +36,6 @@ class MessageStickerSerializationTest: XCTestCase { let deserialized = try NSKeyedUnarchiver.unarchivedObject( ofClass: MessageSticker.self, from: archiverData, - requiringSecureCoding: false, )! try deserialized.validate(against: constant) } catch ValidatableModelError.failedToValidate { diff --git a/SignalServiceKit/tests/Profiles/ProfileManagerTest.swift b/SignalServiceKit/tests/Profiles/ProfileManagerTest.swift index e15966737e..78dcec524a 100644 --- a/SignalServiceKit/tests/Profiles/ProfileManagerTest.swift +++ b/SignalServiceKit/tests/Profiles/ProfileManagerTest.swift @@ -87,7 +87,7 @@ class ProfileManagerTest: XCTestCase { } private static func serialize(_ pendingProfileUpdate: PendingProfileUpdate) throws -> Data { - try NSKeyedArchiver.archivedData(withRootObject: pendingProfileUpdate, requiringSecureCoding: false) + try NSKeyedArchiver.archivedData(withRootObject: pendingProfileUpdate, requiringSecureCoding: true) } private static func deserialize(data: Data) throws -> PendingProfileUpdate { diff --git a/SignalUI/Attachments/TypedItemProvider.swift b/SignalUI/Attachments/TypedItemProvider.swift index ec5c4c97ec..bf7bdf1367 100644 --- a/SignalUI/Attachments/TypedItemProvider.swift +++ b/SignalUI/Attachments/TypedItemProvider.swift @@ -301,7 +301,7 @@ public struct TypedItemProvider { overrideTypeIdentifier: String? = nil, cannotLoadError: ItemProviderError, failedLoadError: ItemProviderError, - ) async throws -> T where T: NSItemProviderReading, T: NSCoding, T: NSObject { + ) async throws -> T where T: NSItemProviderReading, T: NSSecureCoding, T: NSObject { do { guard itemProvider.canLoadObject(ofClass: T.self) else { throw cannotLoadError