Improve fetching of current binaries UUID

- This now also works with unit tests
- Fixed BITStoreUpdateManager for now failed unit tests
- Fixed a typo

Thanks to @0xced !
This commit is contained in:
Andreas Linde 2014-03-27 00:13:27 +01:00
parent 6db478b452
commit b5087a61c4
3 changed files with 28 additions and 20 deletions

View File

@ -38,9 +38,8 @@
#import "BITKeychainUtils.h" #import "BITKeychainUtils.h"
#import <sys/sysctl.h> #import <sys/sysctl.h>
#if !TARGET_IPHONE_SIMULATOR #import <mach-o/dyld.h>
#import <mach-o/ldsyms.h> #import <mach-o/loader.h>
#endif
#ifndef __IPHONE_6_1 #ifndef __IPHONE_6_1
#define __IPHONE_6_1 60100 #define __IPHONE_6_1 60100
@ -134,29 +133,38 @@
} }
- (NSString *)executableUUID { - (NSString *)executableUUID {
// This now requires the testing of this feature to be done on an actual device, since it returns always empty strings on the simulator const struct mach_header *executableHeader = NULL;
// Once there is a better solution to get unit test targets build without problems this should be changed again, so testing of this for (uint32_t i = 0; i < _dyld_image_count(); i++) {
// feature is also possible using the simulator const struct mach_header *header = _dyld_get_image_header(i);
// See: http://support.hockeyapp.net/discussions/problems/2306-integrating-hockeyapp-with-test-bundle-target-i386-issues if (header->filetype == MH_EXECUTE) {
// http://support.hockeyapp.net/discussions/problems/4113-linking-hockeysdk-to-test-bundle-target executableHeader = header;
#if !TARGET_IPHONE_SIMULATOR break;
const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1); }
for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) { }
const struct load_command *load_command = (const struct load_command *)command;
if (load_command->cmd == LC_UUID) { if (!executableHeader)
const struct uuid_command *uuid_command = (const struct uuid_command *)command; return @"";
const uint8_t *uuid = uuid_command->uuid;
#ifdef __LP64__
uintptr_t cursor = (uintptr_t)executableHeader + sizeof(struct mach_header_64);
#else
uintptr_t cursor = (uintptr_t)executableHeader + sizeof(struct mach_header);
#endif
const struct segment_command *segmentCommand = NULL;
for (uint32_t i = 0; i < executableHeader->ncmds; i++, cursor += segmentCommand->cmdsize) {
segmentCommand = (struct segment_command *)cursor;
if (segmentCommand->cmd == LC_UUID) {
const struct uuid_command *uuidCommand = (const struct uuid_command *)segmentCommand;
const uint8_t *uuid = uuidCommand->uuid;
return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", return [[NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
uuid[0], uuid[1], uuid[2], uuid[3], uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7], uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11], uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]] uuid[12], uuid[13], uuid[14], uuid[15]]
lowercaseString]; lowercaseString];
} else {
command += load_command->cmdsize;
} }
} }
#endif
return @""; return @"";
} }

View File

@ -155,7 +155,7 @@
if ([self.userDefaults objectForKey:kBITStoreUpdateLastUUID]) { if ([self.userDefaults objectForKey:kBITStoreUpdateLastUUID]) {
lastSavedUUID = [self.userDefaults objectForKey:kBITStoreUpdateLastUUID]; lastSavedUUID = [self.userDefaults objectForKey:kBITStoreUpdateLastUUID];
if (lastSavedUUID && ![lastSavedUUID isEqualToString:_currentUUID]) { if (lastSavedUUID && [lastSavedUUID length] > 0 && ![lastSavedUUID isEqualToString:_currentUUID]) {
// the UUIDs don't match, store the new one // the UUIDs don't match, store the new one
[self.userDefaults setObject:_currentUUID forKey:kBITStoreUpdateLastUUID]; [self.userDefaults setObject:_currentUUID forKey:kBITStoreUpdateLastUUID];

View File

@ -300,7 +300,7 @@
STAssertFalse(result, @"The newer version is being ignored"); STAssertFalse(result, @"The newer version is being ignored");
} }
- (void)testReportedVersionIsNewerThanTHeIgnoredVersion { - (void)testReportedVersionIsNewerThanTheIgnoredVersion {
NSUserDefaults *mockUserDefaults = mock([NSUserDefaults class]); NSUserDefaults *mockUserDefaults = mock([NSUserDefaults class]);
[given([mockUserDefaults objectForKey:@"BITStoreUpdateLastStoreVersion"]) willReturn:@"4.1.1"]; [given([mockUserDefaults objectForKey:@"BITStoreUpdateLastStoreVersion"]) willReturn:@"4.1.1"];
[given([mockUserDefaults objectForKey:@"BITStoreUpdateLastUUID"]) willReturn:@""]; [given([mockUserDefaults objectForKey:@"BITStoreUpdateLastUUID"]) willReturn:@""];