Permalink
Browse files

Fixed issues that led to crashes on Mac OS X 10.7 Lion.

These fixes remove the use of the File Manager API that was causing crashes on Lion. This should resolve issue #827357. We are now using NSFileManager instead of the older File Manager API, but only on 10.6 and later. These changes should work for those targeting 10.4, but will allow users running 10.7 to still update without crashing.
  • Loading branch information...
1 parent fc725cc commit 613b759077e5b66cc0fc80f1cafa043ddf4ada69 @cocoabythefire cocoabythefire committed Oct 17, 2011
Showing with 66 additions and 25 deletions.
  1. +18 −9 SUDiskImageUnarchiver.m
  2. +48 −16 SUPlainInstallerInternals.m
View
@@ -65,15 +65,24 @@ - (void)extractDMG
mountedSuccessfully = YES;
// Now that we've mounted it, we need to copy out its contents.
- FSRef srcRef, dstRef;
- OSStatus err;
- err = FSPathMakeRef((UInt8 *)[mountPoint fileSystemRepresentation], &srcRef, NULL);
- if (err != noErr) goto reportError;
- err = FSPathMakeRef((UInt8 *)[[archivePath stringByDeletingLastPathComponent] fileSystemRepresentation], &dstRef, NULL);
- if (err != noErr) goto reportError;
-
- err = FSCopyObjectSync(&srcRef, &dstRef, (CFStringRef)mountPointName, NULL, kFSFileOperationSkipSourcePermissionErrors);
- if (err != noErr) goto reportError;
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
+ // On 10.6 and later we don't want to use the File Manager API and instead want to use NSFileManager (fixes #827357).
+ NSFileManager *manager = [[NSFileManager alloc] init];
+ if (![manager copyItemAtPath:mountPoint toPath:[archivePath stringByDeletingLastPathComponent] error:NULL]) {
+ goto reportError;
+ }
+ }
+ else {
+ FSRef srcRef, dstRef;
+ OSStatus err;
+ err = FSPathMakeRef((UInt8 *)[mountPoint fileSystemRepresentation], &srcRef, NULL);
+ if (err != noErr) goto reportError;
+ err = FSPathMakeRef((UInt8 *)[[archivePath stringByDeletingLastPathComponent] fileSystemRepresentation], &dstRef, NULL);
+ if (err != noErr) goto reportError;
+
+ err = FSCopyObjectSync(&srcRef, &dstRef, (CFStringRef)mountPointName, NULL, kFSFileOperationSkipSourcePermissionErrors);
+ if (err != noErr) goto reportError;
+ }
[self performSelectorOnMainThread:@selector(notifyDelegateOfSuccess) withObject:nil waitUntilDone:NO];
goto finally;
@@ -461,26 +461,58 @@ + (BOOL)copyPathWithAuthentication:(NSString *)src overPath:(NSString *)dst temp
err = FSPathMakeRef((UInt8 *)[[dst stringByDeletingLastPathComponent] fileSystemRepresentation], &dstDirRef, NULL);
if (err == noErr && hadFileAtDest)
- {
- err = FSMoveObjectSync(&dstRef, &tmpDirRef, (CFStringRef)[tmpPath lastPathComponent], &movedRef, 0);
- }
- if (err != noErr && hadFileAtDest)
- {
- if (error != NULL)
- *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't move %@ to %@.", dst, tmpPath] forKey:NSLocalizedDescriptionKey]];
- return NO;
+ {
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5)
+ {
+ NSFileManager *manager = [[NSFileManager alloc] init];
+ BOOL success = [manager moveItemAtPath:dst toPath:tmpPath error:error];
+ if (!success && hadFileAtDest)
+ {
+ if (error != NULL)
+ *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't move %@ to %@.", dst, tmpPath] forKey:NSLocalizedDescriptionKey]];
+ return NO;
+ }
+
+ } else {
+ err = FSMoveObjectSync(&dstRef, &tmpDirRef, (CFStringRef)[tmpPath lastPathComponent], &movedRef, 0);
+ if (err != noErr && hadFileAtDest)
+ {
+ if (error != NULL)
+ *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't move %@ to %@.", dst, tmpPath] forKey:NSLocalizedDescriptionKey]];
+ return NO;
+ }
+ }
}
+
err = FSPathMakeRef((UInt8 *)[src fileSystemRepresentation], &srcRef, NULL);
if (err == noErr)
- err = FSCopyObjectSync(&srcRef, &dstDirRef, (CFStringRef)[dst lastPathComponent], NULL, 0);
- if (err != noErr)
{
- // We better move the old version back to its old location
- if( hadFileAtDest )
- FSMoveObjectSync(&movedRef, &dstDirRef, (CFStringRef)[dst lastPathComponent], &movedRef, 0);
- if (error != NULL)
- *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't copy %@ to %@.", src, dst] forKey:NSLocalizedDescriptionKey]];
- return NO;
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5)
+ {
+ NSFileManager *manager = [[NSFileManager alloc] init];
+ BOOL success = [manager copyItemAtPath:src toPath:dst error:error];
+ if (!success)
+ {
+ // We better move the old version back to its old location
+ if( hadFileAtDest )
+ success = [manager moveItemAtPath:tmpPath toPath:dst error:error];
+ if (error != NULL)
+ *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't move %@ to %@.", dst, tmpPath] forKey:NSLocalizedDescriptionKey]];
+ return NO;
+
+ }
+ } else {
+ err = FSCopyObjectSync(&srcRef, &dstDirRef, (CFStringRef)[dst lastPathComponent], NULL, 0);
+ if (err != noErr)
+ {
+ // We better move the old version back to its old location
+ if( hadFileAtDest )
+ FSMoveObjectSync(&movedRef, &dstDirRef, (CFStringRef)[dst lastPathComponent], &movedRef, 0);
+ if (error != NULL)
+ *error = [NSError errorWithDomain:SUSparkleErrorDomain code:SUFileCopyFailure userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Couldn't copy %@ to %@.", src, dst] forKey:NSLocalizedDescriptionKey]];
+ return NO;
+ }
+ }
}
// If the currently-running application is trusted, the new

3 comments on commit 613b759

So, I notice you are allocating a new NSFileManager. I'm assuming you are doing that because this is running on a thread? But in any case, I think you want to release it and not leak it....

Contributor

cocoabythefire replied Oct 20, 2011

Dan, yes of course! I am so used to using Garbage Collection/ARC. I will push an update.

This comment from a similar pull request could be relevant here in regards to .dmg files.

Please sign in to comment.