Skip to content

Commit 34c4bdb

Browse files
Replace NSCoding with NSSecureCoding (#7831)
1 parent b163ec5 commit 34c4bdb

10 files changed

+81
-73
lines changed

FirebaseMessaging/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# 2021-04 -- v7.11.0
22
- [changed] Refactor Messaging to internally not depending on InstanceID, but can co-exist. Will remove InstanceID dependency in the next Firebase breaking change. (#7814)
3+
- [changed] Replaced NSCoding with NSSecureCoding. (#7831)
34

45
# 2021-02 -- v7.7.0
56
- [fixed] Fixed an issue in which, when checking storage size before writing to disk, the client was checking document folders that were no longer used. (#7480)

FirebaseMessaging/Sources/FIRMessagingCode.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) {
220220
kFIRMessagingMessageCodeTokenManagerAPNSChangedTokenInvalidated = 34011,
221221
kFIRMessagingMessageCodeTokenManagerInvalidateStaleToken = 34012,
222222
// FIRMessagingTokenStore.m
223-
// DO NOT USE 15002 - 15013
223+
// DO NOT USE 35002 - 35013
224224
kFIRMessagingMessageCodeTokenStore000 = 35000,
225225
kFIRMessagingMessageCodeTokenStore001 = 35001,
226-
kFIRMessagingMessageCodeTokenStoreExceptionUnarchivingTokenInfo = 35015,
227-
226+
kFIRMessagingMessageCodeTokenStoreUnarchivingTokenInfo = 35015,
227+
kFIRMessagingMessageCodeTokenStoreArchiveError = 35016,
228228
// DO NOT USE 16000, 18004
229229

230230
// FIRMessagingUtilities.m

FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
2222
* Represents an APNS device token and whether its environment is for sandbox.
2323
* It can read from and write to an NSDictionary for simple serialization.
2424
*/
25-
@interface FIRMessagingAPNSInfo : NSObject <NSCoding, NSCopying>
25+
@interface FIRMessagingAPNSInfo : NSObject <NSSecureCoding, NSCopying>
2626

2727
/// The APNs device token, provided by the OS to the application delegate
2828
@property(nonatomic, readonly, copy) NSData *deviceToken;

FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ - (id)copyWithZone:(NSZone *)zone {
6868
return clone;
6969
}
7070

71-
#pragma mark - NSCoding
71+
#pragma mark - NSSecureCoding
72+
73+
+ (BOOL)supportsSecureCoding {
74+
return YES;
75+
}
7276

7377
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
7478
id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey];

FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
2525
* associated with it. It can read from and write to an NSDictionary object, for
2626
* simple serialization.
2727
*/
28-
@interface FIRMessagingTokenInfo : NSObject <NSCoding>
28+
@interface FIRMessagingTokenInfo : NSObject <NSSecureCoding>
2929

3030
/// The authorized entity (also known as Sender ID), associated with the token.
3131
@property(nonatomic, readonly, copy) NSString *authorizedEntity;

FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.m

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
1818

19+
#import <GoogleUtilities/GULSecureCoding.h>
1920
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
2021
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
2122
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
@@ -119,7 +120,11 @@ - (BOOL)isDefaultToken {
119120
return [self.scope isEqualToString:kFIRMessagingDefaultTokenScope];
120121
}
121122

122-
#pragma mark - NSCoding
123+
#pragma mark - NSSecureCoding
124+
125+
+ (BOOL)supportsSecureCoding {
126+
return YES;
127+
}
123128

124129
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
125130
// These value cannot be nil
@@ -140,7 +145,6 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
140145
}
141146

142147
// These values are nullable, so only fail the decode if the type does not match
143-
144148
id appVersion = [aDecoder decodeObjectForKey:kFIRInstanceIDAppVersionKey];
145149
if (appVersion && ![appVersion isKindOfClass:[NSString class]]) {
146150
return nil;
@@ -158,19 +162,15 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
158162

159163
FIRMessagingAPNSInfo *APNSInfo = nil;
160164
if (rawAPNSInfo) {
161-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
162-
@try {
163-
[NSKeyedUnarchiver setClass:[FIRMessagingAPNSInfo class]
164-
forClassName:@"FIRInstanceIDAPNSInfo"];
165-
#pragma clang diagnostic push
166-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
167-
APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo];
168-
#pragma clang diagnostic pop
169-
} @catch (NSException *exception) {
170-
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
171-
@"Could not parse raw APNS Info while parsing archived token info.");
172-
APNSInfo = nil;
173-
} @finally {
165+
NSError *error;
166+
APNSInfo = [GULSecureCoding
167+
unarchivedObjectOfClasses:[NSSet setWithObjects:FIRMessagingAPNSInfo.class, nil]
168+
fromData:rawAPNSInfo
169+
error:&error];
170+
if (error) {
171+
FIRMessagingLoggerDebug(
172+
kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
173+
@"Could not parse raw APNS Info while parsing unarchived token info: %@", error);
174174
}
175175
}
176176

@@ -200,15 +200,15 @@ - (void)encodeWithCoder:(NSCoder *)aCoder {
200200
[aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey];
201201
NSData *rawAPNSInfo;
202202
if (self.APNSInfo) {
203-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
204-
[NSKeyedArchiver setClassName:@"FIRInstanceIDAPNSInfo" forClass:[FIRMessagingAPNSInfo class]];
205-
#pragma clang diagnostic push
206-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
207-
rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo];
208-
#pragma clang diagnostic pop
209-
210-
[aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
203+
NSError *error;
204+
rawAPNSInfo = [GULSecureCoding archivedDataWithRootObject:self.APNSInfo error:&error];
205+
if (error) {
206+
FIRMessagingLoggerDebug(
207+
kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
208+
@"Could not parse raw APNS Info while parsing archived token info: %@", error);
209+
}
211210
}
211+
[aCoder encodeObject:[rawAPNSInfo copy] forKey:kFIRInstanceIDAPNSInfoKey];
212212
[aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey];
213213
}
214214

FirebaseMessaging/Sources/Token/FIRMessagingTokenStore.m

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenStore.h"
1818

19+
#import <GoogleUtilities/GULSecureCoding.h>
1920
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
2021
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
2122
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
@@ -87,21 +88,18 @@ + (nullable FIRMessagingTokenInfo *)tokenInfoFromKeychainItem:(NSData *)item {
8788
// NOTE: Passing in nil to unarchiveObjectWithData will result in an iOS error logged
8889
// in the console on iOS 10 and below. Avoid by checking item.data's existence.
8990
if (item) {
90-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
91-
@try {
92-
#pragma clang diagnostic push
93-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
94-
[NSKeyedUnarchiver setClass:[FIRMessagingTokenInfo class]
95-
forClassName:@"FIRInstanceIDTokenInfo"];
96-
tokenInfo = [NSKeyedUnarchiver unarchiveObjectWithData:item];
97-
#pragma clang diagnostic pop
98-
99-
} @catch (NSException *exception) {
100-
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenStoreExceptionUnarchivingTokenInfo,
91+
NSError *unarchiverError;
92+
tokenInfo = [GULSecureCoding
93+
unarchivedObjectOfClasses:[NSSet
94+
setWithObjects:FIRMessagingTokenInfo.class, NSDate.class, nil]
95+
fromData:item
96+
error:&unarchiverError];
97+
if (unarchiverError) {
98+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenStoreUnarchivingTokenInfo,
10199
@"Unable to parse token info from Keychain item; item was in an "
102-
@"invalid format");
100+
@"invalid format %@",
101+
unarchiverError);
103102
tokenInfo = nil;
104-
} @finally {
105103
}
106104
}
107105
return tokenInfo;
@@ -115,13 +113,13 @@ - (void)saveTokenInfo:(FIRMessagingTokenInfo *)tokenInfo
115113
handler:(void (^)(NSError *))handler { // Keep the cachetime up-to-date.
116114
tokenInfo.cacheTime = [NSDate date];
117115
// Always write to the Keychain, so that the cacheTime is up-to-date.
118-
NSData *tokenInfoData;
119-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
120-
[NSKeyedArchiver setClassName:@"FIRInstanceIDTokenInfo" forClass:[FIRMessagingTokenInfo class]];
121-
#pragma clang diagnostic push
122-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
123-
tokenInfoData = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
124-
#pragma clang diagnostic pop
116+
NSError *archiverError;
117+
NSData *tokenInfoData = [GULSecureCoding archivedDataWithRootObject:tokenInfo
118+
error:&archiverError];
119+
if (archiverError) {
120+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenStoreArchiveError,
121+
@"Failed to archive token info: %@", archiverError);
122+
}
125123
NSString *account = FIRMessagingAppIdentifier();
126124
NSString *service = [[self class] serviceKeyForAuthorizedEntity:tokenInfo.authorizedEntity
127125
scope:tokenInfo.scope];
@@ -130,14 +128,15 @@ - (void)saveTokenInfo:(FIRMessagingTokenInfo *)tokenInfo
130128

131129
- (void)saveTokenInfoInCache:(FIRMessagingTokenInfo *)tokenInfo {
132130
tokenInfo.cacheTime = [NSDate date];
133-
// TODO(chliangGoogle): Use the new API and secureCoding protocol.
134131
// Always write to the Keychain, so that the cacheTime is up-to-date.
135-
NSData *tokenInfoData;
136-
[NSKeyedArchiver setClassName:@"FIRInstanceIDTokenInfo" forClass:[FIRMessagingTokenInfo class]];
137-
#pragma clang diagnostic push
138-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
139-
tokenInfoData = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
140-
#pragma clang diagnostic pop
132+
NSError *archiverError;
133+
NSData *tokenInfoData = [GULSecureCoding archivedDataWithRootObject:tokenInfo
134+
error:&archiverError];
135+
if (archiverError) {
136+
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenStoreArchiveError,
137+
@"Failed to archive token info: %@", archiverError);
138+
}
139+
141140
NSString *account = FIRMessagingAppIdentifier();
142141
NSString *service = [[self class] serviceKeyForAuthorizedEntity:tokenInfo.authorizedEntity
143142
scope:tokenInfo.scope];

FirebaseMessaging/Tests/UnitTests/FIRMessagingAPNSInfoTest.m

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#import <XCTest/XCTest.h>
1818

19+
#import <GoogleUtilities/GULSecureCoding.h>
1920
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
2021
#import "FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.h"
2122

@@ -76,11 +77,13 @@ - (void)testAPNSInfoEncodingAndDecoding {
7677
};
7778
FIRMessagingAPNSInfo *info =
7879
[[FIRMessagingAPNSInfo alloc] initWithTokenOptionsDictionary:validDictionary];
79-
#pragma clang diagnostic push
80-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
81-
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info];
82-
FIRMessagingAPNSInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
83-
#pragma clang diagnostic pop
80+
NSError *error;
81+
NSData *archive = [GULSecureCoding archivedDataWithRootObject:info error:&error];
82+
NSError *unarchiveError;
83+
FIRMessagingAPNSInfo *restoredInfo = [GULSecureCoding
84+
unarchivedObjectOfClasses:[NSSet setWithObjects:FIRMessagingAPNSInfo.class, nil]
85+
fromData:archive
86+
error:&unarchiveError];
8487
XCTAssertEqualObjects(info.deviceToken, restoredInfo.deviceToken);
8588
XCTAssertEqual(info.sandbox, restoredInfo.sandbox);
8689
}

FirebaseMessaging/Tests/UnitTests/FIRMessagingAuthKeychainTest.m

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
#if !TARGET_OS_MACCATALYST && !SWIFT_PACKAGE
1919
// Skip keychain tests on Catalyst and swift package
2020

21+
#import <GoogleUtilities/GULSecureCoding.h>
2122
#import <XCTest/XCTest.h>
22-
#import "OCMock.h"
23-
2423
#import "FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.h"
2524
#import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinPreferences.h"
2625
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
26+
#import "OCMock.h"
2727

2828
static NSString *const kFIRMessagingTestKeychainId = @"com.google.iid-tests";
2929

@@ -406,10 +406,8 @@ - (NSData *)tokenDataWithAuthorizedEntity:(NSString *)authorizedEntity
406406
token:token
407407
appVersion:@"1.0"
408408
firebaseAppID:kFirebaseAppID];
409-
#pragma clang diagnostic push
410-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
411-
return [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
412-
#pragma clang diagnostic pop
409+
NSError *error;
410+
return [GULSecureCoding archivedDataWithRootObject:tokenInfo error:&error];
413411
}
414412
@end
415413

FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenInfoTest.m

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
1818

19+
#import <GoogleUtilities/GULSecureCoding.h>
1920
#import <XCTest/XCTest.h>
20-
2121
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
2222
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
2323
#import "FirebaseMessaging/Sources/Token/FIRMessagingAPNSInfo.h"
@@ -76,11 +76,14 @@ - (void)tearDown {
7676
// yields the same values for all the fields.
7777
- (void)testTokenInfoEncodingAndDecoding {
7878
FIRMessagingTokenInfo *info = self.validTokenInfo;
79-
#pragma clang diagnostic push
80-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
81-
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info];
82-
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
83-
#pragma clang diagnostic pop
79+
NSError *archiverError;
80+
NSData *archive = [GULSecureCoding archivedDataWithRootObject:info error:&archiverError];
81+
NSError *unarchiverError;
82+
FIRMessagingTokenInfo *restoredInfo =
83+
[GULSecureCoding unarchivedObjectOfClasses:[NSSet setWithObjects:FIRMessagingTokenInfo.class,
84+
NSDate.class, nil]
85+
fromData:archive
86+
error:&unarchiverError];
8487
XCTAssertEqualObjects(restoredInfo.authorizedEntity, info.authorizedEntity);
8588
XCTAssertEqualObjects(restoredInfo.scope, info.scope);
8689
XCTAssertEqualObjects(restoredInfo.token, info.token);

0 commit comments

Comments
 (0)