4949static BOOL Trash (NSString *path);
5050static BOOL AuthorizedInstall (NSString *srcPath, NSString *dstPath, BOOL *canceled);
5151static BOOL CopyBundle (NSString *srcPath, NSString *dstPath);
52+ static NSString *ShellQuotedString (NSString *string);
5253static void Relaunch ();
5354
5455// Main worker function
@@ -151,7 +152,7 @@ void PFMoveToApplicationsFolderIfNecessary(void) {
151152
152153 // Use the shell to determine if the app is already running on systems 10.5 or lower
153154 if (floor (NSAppKitVersionNumber ) <= NSAppKitVersionNumber10_5 ) {
154- NSString *script = [NSString stringWithFormat: @" ps ax -o comm | grep ' %@ /' | grep -v grep >/dev/null" , destinationPath];
155+ NSString *script = [NSString stringWithFormat: @" ps ax -o comm | grep %@ / | grep -v grep >/dev/null" , ShellQuotedString ( destinationPath) ];
155156 NSTask *task = [NSTask launchedTaskWithLaunchPath: @" /bin/sh" arguments: [NSArray arrayWithObjects: @" -c" , script, nil ]];
156157 [task waitUntilExit ];
157158
@@ -418,6 +419,10 @@ static BOOL CopyBundle(NSString *srcPath, NSString *dstPath) {
418419 return NO ;
419420}
420421
422+ static NSString *ShellQuotedString (NSString *string) {
423+ return [NSString stringWithFormat: @" '%@ '" , [string stringByReplacingOccurrencesOfString: @" '" withString: @" '\\ ''" ]];
424+ }
425+
421426static void Relaunch (NSString *destinationPath) {
422427 // The shell script waits until the original app process terminates.
423428 // This is done so that the relaunched app opens as the front-most app.
@@ -426,27 +431,29 @@ static void Relaunch(NSString *destinationPath) {
426431 // Command run just before running open /final/path
427432 NSString *preOpenCmd = @" " ;
428433
434+ NSString *quotedDestinationPath = ShellQuotedString (destinationPath);
435+
429436 // OS X >=10.5:
430437 // Before we launch the new app, clear xattr:com.apple.quarantine to avoid
431438 // duplicate "scary file from the internet" dialog.
432439#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
433440 if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_5 ) {
434441 // Add the -r flag on 10.6
435- preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d -r com.apple.quarantine ' %@ '; " , destinationPath ];
442+ preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d -r com.apple.quarantine %@ " , quotedDestinationPath ];
436443 }
437444 else if (floor (NSAppKitVersionNumber ) > NSAppKitVersionNumber10_4 ) {
438- preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d com.apple.quarantine ' %@ '; " , destinationPath ];
445+ preOpenCmd = [NSString stringWithFormat: @" /usr/bin/xattr -d com.apple.quarantine %@ " , quotedDestinationPath ];
439446 }
440447#endif
441448
442- NSString *script = [NSString stringWithFormat: @" (while [ `ps -p %d | wc -l` -gt 1 ]; do sleep 0.1; done; %@ open ' %@ ' ) &" , pid, preOpenCmd, destinationPath ];
449+ NSString *script = [NSString stringWithFormat: @" (while [ `ps -p %d | wc -l` -gt 1 ]; do sleep 0.1; done; %@ ; open %@ ) &" , pid, preOpenCmd, quotedDestinationPath ];
443450
444451 [NSTask launchedTaskWithLaunchPath: @" /bin/sh" arguments: [NSArray arrayWithObjects: @" -c" , script, nil ]];
445452
446453 // Launched from within a DMG? -- unmount (if no files are open after 5 seconds,
447454 // otherwise leave it mounted).
448455 if (IsLaunchedFromDMG ()) {
449- script = [NSString stringWithFormat: @" (sleep 5 && hdiutil detach ' %@ ' ) &" , [[[NSBundle mainBundle ] bundlePath ] stringByDeletingLastPathComponent ]];
456+ script = [NSString stringWithFormat: @" (sleep 5 && hdiutil detach %@ ) &" , ShellQuotedString ( [[[NSBundle mainBundle ] bundlePath ] stringByDeletingLastPathComponent ]) ];
450457 [NSTask launchedTaskWithLaunchPath: @" /bin/sh" arguments: [NSArray arrayWithObjects: @" -c" , script, nil ]];
451458 }
452459
0 commit comments