2 Commits
Author SHA1 Message Date
Justin Spahr-Summers b1f4ecf615 Merge pull request #143 from Squirrel/quote-paths-when-signing
Quote the paths passed to otool.
2015-02-12 12:15:42 -08:00
Rob Rix fd29bc392f Quote the paths passed to otool.
We pass in a path which could contain spaces, so we need to quote it.
2015-02-12 10:02:32 -05:00
10 changed files with 33 additions and 103 deletions
@@ -14,7 +14,4 @@
// Info.plist, or nil if the key is not present.
@property (nonatomic, copy, readonly) NSString *sqrl_bundleVersion;
/// The value of the `kCFBundleExecutableKey` key.
@property (nonatomic, copy, readonly) NSString *sqrl_executableName;
@end
@@ -14,8 +14,4 @@
return [self objectForInfoDictionaryKey:(id)kCFBundleVersionKey];
}
- (NSString *)sqrl_executableName {
return [self objectForInfoDictionaryKey:(id)kCFBundleExecutableKey];
}
@end
+14 -66
View File
@@ -262,49 +262,27 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
setNameWithFormat:@"%@ -acquireTargetBundleURLForRequest: %@", self, request];
}
- (RACSignal *)renameIfNeeded:(SQRLShipItRequest *)request updateBundleURL:(NSURL *)updateBundleURL {
if (!request.useUpdateBundleName) return [RACSignal return:request];
return [[self
renamedTargetIfNeededWithTargetURL:request.targetBundleURL sourceURL:updateBundleURL]
flattenMap:^(NSURL *newTargetURL) {
if ([newTargetURL isEqual:request.targetBundleURL]) return [RACSignal return:request];
SQRLShipItRequest *updatedRequest = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:newTargetURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:request.launchAfterInstallation useUpdateBundleName:request.useUpdateBundleName];
return [[self
installItemToURL:newTargetURL fromURL:request.targetBundleURL]
concat:[RACSignal return:updatedRequest]];
}];
}
- (RACSignal *)installRequest:(SQRLShipItRequest *)request {
NSParameterAssert(request != nil);
return [[[[self
prepareAndValidateUpdateBundleURLForRequest:request]
flattenMap:^(NSURL *updateBundleURL) {
return [[[[self
renameIfNeeded:request updateBundleURL:updateBundleURL]
flattenMap:^(SQRLShipItRequest *request) {
return [[self acquireTargetBundleURLForRequest:request] concat:[RACSignal return:request]];
}]
flattenMap:^(SQRLShipItRequest *request) {
return [[[[[[self
installItemToURL:request.targetBundleURL fromURL:updateBundleURL]
concat:[RACSignal return:request.updateBundleURL]]
concat:[RACSignal return:updateBundleURL]]
concat:[RACSignal defer:^{
return [RACSignal return:self.ownedBundle.temporaryURL];
}]]
flattenMap:^(NSURL *location) {
return [[[self
deleteOwnedBundleAtURL:location]
doError:^(NSError *error) {
NSLog(@"Couldn't remove owned bundle at location %@, error %@", location, error.sqrl_verboseDescription);
}]
catchTo:[RACSignal empty]];
return [[[[[[[self
acquireTargetBundleURLForRequest:request]
concat:[self installItemToURL:request.targetBundleURL fromURL:updateBundleURL]]
concat:[RACSignal return:request.updateBundleURL]]
concat:[RACSignal return:updateBundleURL]]
concat:[RACSignal defer:^{
return [RACSignal return:self.ownedBundle.temporaryURL];
}]]
flattenMap:^(NSURL *location) {
return [[[self
deleteOwnedBundleAtURL:location]
doError:^(NSError *error) {
NSLog(@"Couldn't remove owned bundle at location %@, error %@", location, error.sqrl_verboseDescription);
}]
concat:[RACSignal return:request]];
catchTo:[RACSignal empty]];
}]
doCompleted:^{
self.ownedBundle = nil;
@@ -435,36 +413,6 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
#pragma mark Installation
/// Check if the target should be renamed and provide the renamed URL.
///
/// targetURL - The URL for the target. Cannot be nil.
/// sourceURL - The URL for the source. Cannot be nil.
///
/// Returns a signal which will send the URL for the renamed target. If a rename
/// isn't needed then it will send `targetURL`.
- (RACSignal *)renamedTargetIfNeededWithTargetURL:(NSURL *)targetURL sourceURL:(NSURL *)sourceURL {
return [RACSignal defer:^{
NSBundle *sourceBundle = [NSBundle bundleWithURL:sourceURL];
NSString *targetExecutableName = targetURL.lastPathComponent.stringByDeletingPathExtension;
NSString *sourceExecutableName = sourceBundle.sqrl_executableName;
// If they're already the same then we're good.
if ([targetExecutableName isEqual:sourceExecutableName]) {
return [RACSignal return:targetURL];
}
NSString *newAppName = [sourceExecutableName stringByAppendingPathExtension:@"app"];
NSURL *newTargetURL = [targetURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:newAppName];
// If there's already something there then don't rename to it.
if ([NSFileManager.defaultManager fileExistsAtPath:newTargetURL.path]) {
return [RACSignal return:targetURL];
}
return [RACSignal return:newTargetURL];
}];
}
- (RACSignal *)installItemToURL:(NSURL *)targetURL fromURL:(NSURL *)sourceURL {
NSParameterAssert(targetURL != nil);
NSParameterAssert(sourceURL != nil);
+1 -5
View File
@@ -73,11 +73,10 @@ extern NSString * const SQRLShipItRequestPropertyErrorKey;
// installing. Can be nil.
// launchAfterInstallation - Whether the updated application should be launched
// after installation.
// useUpdateBundleName - Should the target use the update bundle's name?
//
// Returns a request which can be written to disk for ShipIt to read and
// perform.
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation useUpdateBundleName:(BOOL)useUpdateBundleName;
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation;
// The URL to the downloaded update's app bundle.
@property (nonatomic, copy, readonly) NSURL *updateBundleURL;
@@ -94,7 +93,4 @@ extern NSString * const SQRLShipItRequestPropertyErrorKey;
// Whether to launch the application after an update is successfully installed.
@property (nonatomic, assign, readonly) BOOL launchAfterInstallation;
// Whether the app should use the update bundle's name.
@property (nonatomic, assign, readonly) BOOL useUpdateBundleName;
@end
+1 -2
View File
@@ -47,13 +47,12 @@ NSString * const SQRLShipItRequestPropertyErrorKey = @"SQRLShipItRequestProperty
return self;
}
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation useUpdateBundleName:(BOOL)useUpdateBundleName {
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation {
return [self initWithDictionary:@{
@keypath(self.updateBundleURL): updateBundleURL,
@keypath(self.targetBundleURL): targetBundleURL,
@keypath(self.bundleIdentifier): bundleIdentifier ?: NSNull.null,
@keypath(self.launchAfterInstallation): @(launchAfterInstallation),
@keypath(self.useUpdateBundleName): @(useUpdateBundleName),
} error:NULL];
}
+2 -7
View File
@@ -528,12 +528,7 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
return [[[[RACSignal
defer:^{
NSRunningApplication *currentApplication = NSRunningApplication.currentApplication;
NSBundle *appBundle = [NSBundle bundleWithURL:currentApplication.bundleURL];
// Only use the update bundle's name if the user hasn't renamed the
// app themselves.
BOOL useUpdateBundleName = [appBundle.sqrl_executableName isEqual:currentApplication.bundleURL.lastPathComponent.stringByDeletingPathExtension];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:update.bundle.bundleURL targetBundleURL:currentApplication.bundleURL bundleIdentifier:currentApplication.bundleIdentifier launchAfterInstallation:NO useUpdateBundleName:useUpdateBundleName];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:update.bundle.bundleURL targetBundleURL:currentApplication.bundleURL bundleIdentifier:currentApplication.bundleIdentifier launchAfterInstallation:NO];
return [request writeUsingURL:self.shipItStateURL];
}]
then:^{
@@ -547,7 +542,7 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
return [[[[[[[[SQRLShipItRequest
readUsingURL:self.shipItStateURL]
map:^(SQRLShipItRequest *request) {
return [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:request.targetBundleURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:YES useUpdateBundleName:request.useUpdateBundleName];
return [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:request.targetBundleURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:YES];
}]
flattenMap:^(SQRLShipItRequest *request) {
return [[request
+4 -5
View File
@@ -75,7 +75,7 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
RACSignal *action;
if (attempt > SQRLShipItMaximumInstallationAttempts) {
action = [[[[installer.abortInstallationCommand
action = [[[installer.abortInstallationCommand
execute:request]
initially:^{
NSLog(@"Too many attempts to install, aborting update");
@@ -86,8 +86,7 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
// Exit successfully so launchd doesn't restart us
// again.
return [RACSignal empty];
}]
concat:[RACSignal return:request]];
}];
} else {
action = [[[[installer.installUpdateCommand
execute:request]
@@ -115,8 +114,8 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
// Launch regardless of whether installation succeeds or fails.
action = [[action
deliverOn:RACScheduler.mainThreadScheduler]
doNext:^(SQRLShipItRequest *finalRequest) {
NSURL *bundleURL = finalRequest.targetBundleURL;
finally:^{
NSURL *bundleURL = request.targetBundleURL;
if (bundleURL == nil) {
NSLog(@"Missing target bundle URL, cannot launch application");
return;
+9 -9
View File
@@ -40,7 +40,7 @@ beforeEach(^{
});
it(@"should install an update using ShipIt", ^{
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
@@ -48,7 +48,7 @@ it(@"should install an update using ShipIt", ^{
});
it(@"should install an update in process", ^{
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:NO];
@@ -60,7 +60,7 @@ it(@"should install an update and relaunch", ^{
NSArray *apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:bundleIdentifier];
expect(@(apps.count)).to(equal(@0));
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:YES useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:YES];
[self installWithRequest:request remote:YES];
@@ -72,7 +72,7 @@ it(@"should install an update from another volume", ^{
NSURL *diskImageURL = [self createAndMountDiskImageNamed:@"TestApplication 2.1" fromDirectory:updateURL.URLByDeletingLastPathComponent];
updateURL = [diskImageURL URLByAppendingPathComponent:updateURL.lastPathComponent];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
@@ -83,7 +83,7 @@ it(@"should install an update to another volume", ^{
NSURL *diskImageURL = [self createAndMountDiskImageNamed:@"TestApplication" fromDirectory:self.testApplicationURL.URLByDeletingLastPathComponent];
NSURL *targetURL = [diskImageURL URLByAppendingPathComponent:self.testApplicationURL.lastPathComponent];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
@@ -118,7 +118,7 @@ describe(@"with backup restoration", ^{
});
it(@"should not install an update after too many attempts", ^{
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
__block NSError *error;
@@ -129,7 +129,7 @@ describe(@"with backup restoration", ^{
});
it(@"should relaunch even after failing to install an update", ^{
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:YES useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:YES];
[self installWithRequest:request remote:YES];
expect(@([NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.github.Squirrel.TestApplication"].count)).toEventually(equal(@1));
@@ -149,7 +149,7 @@ it(@"should disallow writing the updated application except by the owner", ^{
expect(@(modeOfURL(updateURL))).to(equal(@0777));
expect(@(modeOfURL([updateURL URLByAppendingPathComponent:@"Contents/MacOS/TestApplication"]))).to(equal(@0777));
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
@@ -178,7 +178,7 @@ describe(@"signal handling", ^{
// accessing the property.
targetURL = self.testApplicationURL;
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
[self installWithRequest:request remote:YES];
+1 -1
View File
@@ -25,7 +25,7 @@ beforeEach(^{
directoryManager = SQRLDirectoryManager.currentApplicationManager;
NSURL *updateURL = [self createTestApplicationUpdate];
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
expect(request).notTo(beNil());
expect(request.targetBundleURL).to(equal(self.testApplicationURL));
+1 -1
View File
@@ -95,7 +95,7 @@ module Targets
# Look for an __TEXT,__info_plist section
# This contains the CFBundleIdentifier necessary for signing
`otool -l #{path}` =~ /__info_plist/
`otool -l "#{path}"` =~ /__info_plist/
end
end