diff --git a/External/diffmatchpatch/DiffMatchPatch.m b/External/diffmatchpatch/DiffMatchPatch.m index 0775d119..92039d15 100755 --- a/External/diffmatchpatch/DiffMatchPatch.m +++ b/External/diffmatchpatch/DiffMatchPatch.m @@ -1503,7 +1503,26 @@ - (NSString *)diff_text2:(NSMutableArray *)diffs; - (NSString *)diff_toDelta:(NSMutableArray *)diffs; { NSMutableString *delta = [NSMutableString string]; + unichar lastEnd = 0; + for (Diff *aDiff in diffs) { + + unichar thisTop = [aDiff.text characterAtIndex:0]; + unichar thisEnd = [aDiff.text characterAtIndex:(aDiff.text.length - 1)]; + + if (CFStringIsSurrogateHighCharacter(thisEnd)) { + aDiff.text = [aDiff.text substringToIndex:(aDiff.text.length - 1)]; + } + + if (lastEnd != 0 && CFStringIsSurrogateHighCharacter(lastEnd) && CFStringIsSurrogateLowCharacter(thisTop)) { + aDiff.text = [NSString stringWithFormat:@"%C%@", lastEnd, aDiff.text]; + } + + lastEnd = thisEnd; + if (0 == [aDiff.text length]) { + continue; + } + switch (aDiff.operation) { case DIFF_INSERT: [delta appendFormat:@"+%@\t", [[aDiff.text diff_stringByAddingPercentEscapesForEncodeUriCompatibility] diff --git a/Simperium/SPEnvironment.m b/Simperium/SPEnvironment.m index 04cfc1a2..eddf47dd 100644 --- a/Simperium/SPEnvironment.m +++ b/Simperium/SPEnvironment.m @@ -30,7 +30,7 @@ #endif // TODO: Update this automatically via a script that looks at current git tag -NSString* const SPLibraryVersion = @"0.8.23"; +NSString* const SPLibraryVersion = @"0.8.24"; /// SSL Pinning /// diff --git a/SimperiumTests/DiffMatchPatchTest.m b/SimperiumTests/DiffMatchPatchTest.m index fbc325c2..635067b5 100755 --- a/SimperiumTests/DiffMatchPatchTest.m +++ b/SimperiumTests/DiffMatchPatchTest.m @@ -48,6 +48,33 @@ - (void)testDiffCommonPrefixTest { XCTAssertEqual((NSUInteger)4, [dmp diff_commonPrefixOfFirstString:@"1234" andSecondString:@"1234xyz"], @"Common suffix whole case failed."); } +- (void)testDiffToDeltaDoesNotProduceNullsWhenDealingWithEmojis { + DiffMatchPatch *dmp = [DiffMatchPatch new]; + + NSString *pristine = @"β˜ΊοΈπŸ––πŸΏ"; + NSString *edited = @"β˜ΊοΈπŸ˜ƒπŸ––πŸΏ"; + NSString *expected = @"=2\t+%F0%9F%98%83\t=4"; + + NSMutableArray *diffs = [dmp diff_mainOfOldString:pristine andNewString:edited]; + NSString *delta = [dmp diff_toDelta:diffs]; + + XCTAssertEqualObjects(delta, expected, @"Delta should match the expected string"); +} + +- (void)testDiffToDeltaWithEmojisCanBeProperlyAppliedToOriginalString { + DiffMatchPatch *dmp = [DiffMatchPatch new]; + + NSString *pristine = @"β˜ΊοΈπŸ––πŸΏ"; + NSString *edited = @"β˜ΊοΈπŸ˜ƒπŸ––πŸΏ"; + + NSMutableArray *diffs = [dmp diff_mainOfOldString:pristine andNewString:edited]; + NSArray *patches = [dmp patch_makeFromDiffs:diffs]; + NSArray *result = [dmp patch_apply:patches toString:pristine]; + + NSString *output = [result firstObject]; + XCTAssertEqualObjects(edited, output, @"Output String should match the Edited one!"); +} + - (void)testDiffCommonSuffixTest { DiffMatchPatch *dmp = [DiffMatchPatch new];