Skip to content

Commit

Permalink
Fixed issue where non-serializable types would get into payload (#937)
Browse files Browse the repository at this point in the history
Co-authored-by: Brandon Sneed <brandon.sneed@segment.com>
  • Loading branch information
bsneed and Brandon Sneed authored Aug 24, 2020
1 parent a73ef3b commit 594d049
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
4 changes: 4 additions & 0 deletions Analytics/Internal/SEGUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ NSString *_Nullable SEGIDFA(void);

NSString *SEGEventNameForScreenTitle(NSString *title);

@interface NSJSONSerialization (Serializable)
+ (BOOL)isOfSerializableType:(id)obj;
@end

// Deep copy and check NSCoding conformance
@protocol SEGSerializableDeepCopy <NSObject>
-(id _Nullable) serializableMutableDeepCopy;
Expand Down
30 changes: 23 additions & 7 deletions Analytics/Internal/SEGUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,20 @@ static id SEGCoerceJSONObject(id obj)
}


@implementation NSJSONSerialization(Serializable)
+ (BOOL)isOfSerializableType:(id)obj
{
if ([obj isKindOfClass:[NSArray class]] ||
[obj isKindOfClass:[NSDictionary class]] ||
[obj isKindOfClass:[NSString class]] ||
[obj isKindOfClass:[NSNumber class]] ||
[obj isKindOfClass:[NSNull class]])
return YES;
return NO;
}
@end


@implementation NSDictionary(SerializableDeepCopy)

- (id)serializableDeepCopy:(BOOL)mutable
Expand All @@ -569,11 +583,12 @@ - (id)serializableDeepCopy:(BOOL)mutable
id aValue = [self objectForKey:key];
id theCopy = nil;

if (![aValue conformsToProtocol:@protocol(NSCoding)]) {
if (![NSJSONSerialization isOfSerializableType:aValue]) {
NSString *className = NSStringFromClass([aValue class]);
#ifdef DEBUG
NSAssert(FALSE, @"key `%@` doesn't conform to NSCoding and can't be serialized for delivery.", key);
NSAssert(FALSE, @"key `%@` is a %@ and can't be serialized for delivery.", key, className);
#else
SEGLog(@"key `%@` doesn't conform to NSCoding and can't be serialized for delivery.", key);
SEGLog(@"key `%@` is a %@ and can't be serializaed for delivery.", key, className);
// simply leave it out since we can't encode it anyway.
continue;
#endif
Expand Down Expand Up @@ -617,16 +632,17 @@ -(id)serializableDeepCopy:(BOOL)mutable
for (id aValue in self) {
id theCopy = nil;

if (![aValue conformsToProtocol:@protocol(NSCoding)]) {
if (![NSJSONSerialization isOfSerializableType:aValue]) {
NSString *className = NSStringFromClass([aValue class]);
#ifdef DEBUG
NSAssert(FALSE, @"type `%@` doesn't conform to NSCoding and can't be serialized for delivery.", NSStringFromClass([aValue class]));
NSAssert(FALSE, @"found a %@ which can't be serialized for delivery.", className);
#else
SEGLog(@"type `%@` doesn't conform to NSCoding and can't be serialized for delivery.", NSStringFromClass([aValue class]));
SEGLog(@"found a %@ which can't be serializaed for delivery.", className);
// simply leave it out since we can't encode it anyway.
continue;
#endif
}

if ([aValue conformsToProtocol:@protocol(SEGSerializableDeepCopy)]) {
theCopy = [aValue serializableDeepCopy:mutable];
} else if ([aValue conformsToProtocol:@protocol(NSCopying)]) {
Expand Down
20 changes: 20 additions & 0 deletions AnalyticsTests/SerializationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#import <XCTest/XCTest.h>
@import Analytics;

@interface NSJSONSerialization (Serializable)
+ (BOOL)isOfSerializableType:(id)obj;
@end

@protocol SEGSerializableDeepCopy <NSObject>
-(id _Nullable) serializableDeepCopy;
@end
Expand Down Expand Up @@ -52,4 +56,20 @@ - (void)testDeepCopyAndConformance {
XCTAssertThrows([nonserializable serializableDeepCopy]);
}

- (void)testDateIssue {
NSDate *date = [NSDate date];
NSString *test = @"test";

XCTAssertFalse([NSJSONSerialization isOfSerializableType:date]);
XCTAssertTrue([NSJSONSerialization isOfSerializableType:test]);

NSDictionary *nonserializable = @{@"test": date};
NSDictionary *serializable = @{@"test": @1};
XCTAssertThrows([nonserializable serializableDeepCopy]);
XCTAssertNoThrow([serializable serializableDeepCopy]);

nonserializable = @{@"test": @[date]};
XCTAssertThrows([nonserializable serializableDeepCopy]);
}

@end
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: b1320b7107926418d81b6d48a9c864abdf9c3eaf

COCOAPODS: 1.9.3
COCOAPODS: 1.9.1

0 comments on commit 594d049

Please sign in to comment.