diff --git a/Sparkle/SUBinaryDeltaCommon.m b/Sparkle/SUBinaryDeltaCommon.m index 6379e1b6..eb8f425e 100644 --- a/Sparkle/SUBinaryDeltaCommon.m +++ b/Sparkle/SUBinaryDeltaCommon.m @@ -195,7 +195,11 @@ extern NSString *hashOfTree(NSString *path) BOOL removeTree(NSString *path) { NSFileManager *fileManager = [NSFileManager defaultManager]; - return ![fileManager fileExistsAtPath:path] ? YES : [fileManager removeItemAtPath:path error:nil]; + // Don't use fileExistsForPath: because it will try to follow symbolic links + if (![fileManager attributesOfItemAtPath:path error:nil]) { + return YES; + } + return [fileManager removeItemAtPath:path error:nil]; } BOOL copyTree(NSString *source, NSString *dest) diff --git a/Tests/SUBinaryDeltaTest.m b/Tests/SUBinaryDeltaTest.m index 5ff66859..1110cf14 100644 --- a/Tests/SUBinaryDeltaTest.m +++ b/Tests/SUBinaryDeltaTest.m @@ -434,6 +434,36 @@ typedef void (^SUDeltaHandler)(NSFileManager *fileManager, NSString *sourceDirec }]; } +- (void)testRemovingSymlink +{ + [self createAndApplyPatchWithHandler:^(NSFileManager *fileManager, NSString *sourceDirectory, NSString *destinationDirectory) { + NSString *sourceFile = [sourceDirectory stringByAppendingPathComponent:@"A"]; + + NSError *error = nil; + if (![fileManager createSymbolicLinkAtPath:sourceFile withDestinationPath:@"B" error:&error]) { + NSLog(@"Error in creating symlink: %@", error); + XCTFail(@"Failed to create symlink"); + } + + XCTAssertFalse([self testDirectoryHashEqualityWithSource:sourceDirectory destination:destinationDirectory]); + }]; +} + +- (void)testAddingSymlink +{ + [self createAndApplyPatchWithHandler:^(NSFileManager *fileManager, NSString *sourceDirectory, NSString *destinationDirectory) { + NSString *destinationFile = [destinationDirectory stringByAppendingPathComponent:@"A"]; + + NSError *error = nil; + if (![fileManager createSymbolicLinkAtPath:destinationFile withDestinationPath:@"B" error:&error]) { + NSLog(@"Error in creating symlink: %@", error); + XCTFail(@"Failed to create symlink"); + } + + XCTAssertFalse([self testDirectoryHashEqualityWithSource:sourceDirectory destination:destinationDirectory]); + }]; +} + - (void)testSmallFilePermissionChangeWithNoContentChange { [self createAndApplyPatchWithHandler:^(NSFileManager *fileManager, NSString *sourceDirectory, NSString *destinationDirectory) {