Skip to content

Commit

Permalink
Properly support NSSecureCoding by listing needed classes.
Browse files Browse the repository at this point in the history
While not clear from the docs, it seems NSDictionary/NSArray when using
SecureCoding will extract strings and numbers just fine, they don't like other
classes unless explicitly listed.

Fixes #298
  • Loading branch information
thomasvl committed Aug 30, 2019
1 parent 5706af8 commit c74959b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
10 changes: 8 additions & 2 deletions Source/Objects/GTLRObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,14 @@ + (BOOL)supportsSecureCoding {
- (instancetype)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self) {
_json = [decoder decodeObjectOfClass:[NSMutableDictionary class]
forKey:kGTLRObjectJSONCoderKey];
// NSDictionary/NSArray seem to allow strings and numbers with secure coding
// just fine, but to allow sub arrays or dictionaries (or an null) the
// classes have to be explicitly listed to decode correctly.
NSSet *expectedClasses =
[NSSet setWithObjects:
[NSMutableDictionary class], [NSMutableArray class], [NSNull class], nil];
_json = [decoder decodeObjectOfClasses:expectedClasses
forKey:kGTLRObjectJSONCoderKey];
}
return self;
}
Expand Down
10 changes: 8 additions & 2 deletions Source/Tests/GTLRObjectTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,14 @@ - (GTLRTestingObject *)objectFromRoundTripArchiveDearchiveWithObject:(GTLRTestin
NSMutableData *data = [NSMutableData data];

NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver setRequiresSecureCoding:YES];
[archiver encodeObject:obj forKey:key];
[archiver finishEncoding];

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
GTLRTestingObject *obj2 = [unarchiver decodeObjectForKey:key];
[unarchiver setRequiresSecureCoding:YES];
GTLRTestingObject *obj2 = [unarchiver decodeObjectOfClass:[obj class]
forKey:key];
[unarchiver finishDecoding];

return obj2;
Expand All @@ -317,14 +320,16 @@ - (void)testSecureCodingEmptyObject {

- (void)testSecureCoding {
NSString * const jsonStr =
@"{\"a_date\":\"2011-01-14T15:00:00Z\",\"a.num\":1234,\"a_str\":\"foo bar\"}";
@"{\"a_date\":\"2011-01-14T15:00:00Z\",\"a.num\":1234,\"a_str\":\"foo bar\","
@"\"arrayString\":null}";
NSError *err = nil;
NSMutableDictionary *json = [self objectWithString:jsonStr
error:&err];
XCTAssertNotNil(json);
GTLRTestingObject *obj = [GTLRTestingObject objectWithJSON:json];
obj.userProperties = @{ @"A" : @1 };
XCTAssertNotNil(obj);
XCTAssertEqual((id)obj.arrayString, (id)[NSNull null]); // pointer comparision

GTLRTestingObject *obj2 = [self objectFromRoundTripArchiveDearchiveWithObject:obj];
XCTAssertNotNil(obj2);
Expand All @@ -333,6 +338,7 @@ - (void)testSecureCoding {
XCTAssertNotEqual(obj2.JSON, obj.JSON);
XCTAssertNil(obj2.userProperties); // userProperties are not encoded.
XCTAssert([obj2.JSON isKindOfClass:[NSMutableDictionary class]]);
XCTAssertEqual((id)obj2.arrayString, (id)[NSNull null]); // pointer comparision
}

- (void)testSecureCodingMutability {
Expand Down

0 comments on commit c74959b

Please sign in to comment.