Skip to content

Commit c26a54a

Browse files
authored
Messaging: Adopt NSSecureCoding for internal classes (#12110)
1 parent b891c92 commit c26a54a

File tree

8 files changed

+69
-63
lines changed

8 files changed

+69
-63
lines changed

FirebaseMessaging/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 10.19.0
2+
- [changed] Adopt NSSecureCoding for internal classes. (#12075)
3+
14
# 10.12.0
25
- [changed] Removing fiam scoped tokens set by old FIAM SDK(s) from keychain if exists (b/284207019).
36

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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ - (id)copyWithZone:(NSZone *)zone {
7070

7171
#pragma mark - NSCoding
7272

73+
+ (BOOL)supportsSecureCoding {
74+
return YES;
75+
}
76+
7377
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
7478
id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey];
7579
if (![deviceToken isKindOfClass:[NSData class]]) {

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: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ - (BOOL)isDefaultToken {
133133
return [self.scope isEqualToString:kFIRMessagingDefaultTokenScope];
134134
}
135135

136-
#pragma mark - NSCoding
136+
#pragma mark - NSSecureCoding
137+
138+
+ (BOOL)supportsSecureCoding {
139+
return YES;
140+
}
137141

138142
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
139143
// These value cannot be nil
@@ -164,30 +168,13 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
164168
if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) {
165169
return nil;
166170
}
167-
168-
id rawAPNSInfo = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoKey];
169-
if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[NSData class]]) {
171+
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingAPNSInfo.class ]];
172+
FIRMessagingAPNSInfo *rawAPNSInfo = [aDecoder decodeObjectOfClasses:classes
173+
forKey:kFIRInstanceIDAPNSInfoKey];
174+
if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[FIRMessagingAPNSInfo class]]) {
170175
return nil;
171176
}
172177

173-
FIRMessagingAPNSInfo *APNSInfo = nil;
174-
if (rawAPNSInfo) {
175-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
176-
@try {
177-
[NSKeyedUnarchiver setClass:[FIRMessagingAPNSInfo class]
178-
forClassName:@"FIRInstanceIDAPNSInfo"];
179-
#pragma clang diagnostic push
180-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
181-
APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo];
182-
#pragma clang diagnostic pop
183-
} @catch (NSException *exception) {
184-
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
185-
@"Could not parse raw APNS Info while parsing archived token info.");
186-
APNSInfo = nil;
187-
} @finally {
188-
}
189-
}
190-
191178
id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey];
192179
if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) {
193180
return nil;
@@ -200,7 +187,7 @@ - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
200187
_token = [token copy];
201188
_appVersion = [appVersion copy];
202189
_firebaseAppID = [firebaseAppID copy];
203-
_APNSInfo = [APNSInfo copy];
190+
_APNSInfo = [rawAPNSInfo copy];
204191
_cacheTime = cacheTime;
205192
}
206193
return self;
@@ -212,16 +199,8 @@ - (void)encodeWithCoder:(NSCoder *)aCoder {
212199
[aCoder encodeObject:self.token forKey:kFIRInstanceIDTokenKey];
213200
[aCoder encodeObject:self.appVersion forKey:kFIRInstanceIDAppVersionKey];
214201
[aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey];
215-
NSData *rawAPNSInfo;
216202
if (self.APNSInfo) {
217-
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
218-
[NSKeyedArchiver setClassName:@"FIRInstanceIDAPNSInfo" forClass:[FIRMessagingAPNSInfo class]];
219-
#pragma clang diagnostic push
220-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
221-
rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo];
222-
#pragma clang diagnostic pop
223-
224-
[aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
203+
[aCoder encodeObject:self.APNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
225204
}
226205
[aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey];
227206
}

FirebaseMessaging/Tests/UnitTests/FIRMessagingAPNSInfoTest.m

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,20 @@ - (void)testAPNSInfoCreationWithInvalidSandboxFormat {
7272
- (void)testAPNSInfoEncodingAndDecoding {
7373
NSDictionary *validDictionary = @{
7474
kFIRMessagingTokenOptionsAPNSKey : [@"tokenData" dataUsingEncoding:NSUTF8StringEncoding],
75-
kFIRMessagingTokenOptionsAPNSIsSandboxKey : @"sandboxValueAsString"
75+
kFIRMessagingTokenOptionsAPNSIsSandboxKey : @1234
7676
};
77+
NSError *error;
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+
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info
81+
requiringSecureCoding:YES
82+
error:&error];
83+
XCTAssertNil(error);
84+
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingAPNSInfo.class, NSData.class ]];
85+
FIRMessagingAPNSInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
86+
fromData:archive
87+
error:&error];
88+
XCTAssertNil(error);
8489
XCTAssertEqualObjects(info.deviceToken, restoredInfo.deviceToken);
8590
XCTAssertEqual(info.sandbox, restoredInfo.sandbox);
8691
}

FirebaseMessaging/Tests/UnitTests/FIRMessagingAuthKeychainTest.m

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,19 @@ - (void)testKeyChainNoCorruptionWithUniqueAccount {
101101
// Now query the token and compare, they should not corrupt
102102
// each other.
103103
NSData *data1 = [weakKeychain dataForService:service account:account1];
104-
#pragma clang diagnostic push
105-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
106104
FIRMessagingTokenInfo *tokenInfo1 =
107-
[NSKeyedUnarchiver unarchiveObjectWithData:data1];
105+
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
106+
fromData:data1
107+
error:&error];
108+
XCTAssertNil(error);
108109
XCTAssertEqualObjects(kToken1, tokenInfo1.token);
109110

110111
NSData *data2 = [weakKeychain dataForService:service account:account2];
111112
FIRMessagingTokenInfo *tokenInfo2 =
112-
[NSKeyedUnarchiver unarchiveObjectWithData:data2];
113-
#pragma clang diagnostic pop
113+
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
114+
fromData:data2
115+
error:&error];
116+
XCTAssertNil(error);
114117
XCTAssertEqualObjects(kToken2, tokenInfo2.token);
115118
// Also check the cache data.
116119
XCTAssertEqual(weakKeychain.cachedKeychainData.count, 1);
@@ -175,11 +178,11 @@ - (void)testKeyChainNoCorruptionWithUniqueService {
175178
// Now query the token and compare, they should not corrupt
176179
// each other.
177180
NSData *data1 = [weakKeychain dataForService:service1 account:account];
178-
#pragma clang diagnostic push
179-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
180181
FIRMessagingTokenInfo *tokenInfo1 =
181-
[NSKeyedUnarchiver unarchiveObjectWithData:data1];
182-
#pragma clang diagnostic pop
182+
[NSKeyedUnarchiver unarchivedObjectOfClass:FIRMessagingTokenInfo.class
183+
fromData:data1
184+
error:&error];
185+
XCTAssertNil(error);
183186
XCTAssertEqualObjects(kToken1, tokenInfo1.token);
184187

185188
NSData *data2 = [weakKeychain dataForService:service2 account:account];
@@ -413,10 +416,12 @@ - (NSData *)tokenDataWithAuthorizedEntity:(NSString *)authorizedEntity
413416
token:token
414417
appVersion:@"1.0"
415418
firebaseAppID:kFirebaseAppID];
416-
#pragma clang diagnostic push
417-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
418-
return [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
419-
#pragma clang diagnostic pop
419+
NSError *error;
420+
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo
421+
requiringSecureCoding:YES
422+
error:&error];
423+
XCTAssertNil(error);
424+
return archive;
420425
}
421426
@end
422427

FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenInfoTest.m

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,16 @@ - (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 *error;
80+
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:info
81+
requiringSecureCoding:YES
82+
error:&error];
83+
XCTAssertNil(error);
84+
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingTokenInfo.class, NSDate.class ]];
85+
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
86+
fromData:archive
87+
error:&error];
88+
XCTAssertNil(error);
8489
XCTAssertEqualObjects(restoredInfo.authorizedEntity, info.authorizedEntity);
8590
XCTAssertEqualObjects(restoredInfo.scope, info.scope);
8691
XCTAssertEqualObjects(restoredInfo.token, info.token);
@@ -101,11 +106,16 @@ - (void)testTokenInfoEncodingAndDecodingWithMissingFields {
101106
token:kToken
102107
appVersion:nil
103108
firebaseAppID:nil];
104-
#pragma clang diagnostic push
105-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
106-
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:sparseInfo];
107-
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchiveObjectWithData:archive];
108-
#pragma clang diagnostic pop
109+
NSError *error;
110+
NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:sparseInfo
111+
requiringSecureCoding:YES
112+
error:&error];
113+
XCTAssertNil(error);
114+
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingTokenInfo.class, NSDate.class ]];
115+
FIRMessagingTokenInfo *restoredInfo = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
116+
fromData:archive
117+
error:&error];
118+
XCTAssertNil(error);
109119
XCTAssertEqualObjects(restoredInfo.authorizedEntity, sparseInfo.authorizedEntity);
110120
XCTAssertEqualObjects(restoredInfo.scope, sparseInfo.scope);
111121
XCTAssertEqualObjects(restoredInfo.token, sparseInfo.token);

0 commit comments

Comments
 (0)