From ebeae2608df53662c141145d6cb4314b5edf5364 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 7 Nov 2016 18:33:51 -0500 Subject: [PATCH] Fix crash on messaging unregistered user // FREEBIE --- src/Contacts/ContactsUpdater.h | 2 +- src/Contacts/ContactsUpdater.m | 14 ++++++++++---- tests/TestSupport/Fakes/OWSFakeContactsUpdater.m | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Contacts/ContactsUpdater.h b/src/Contacts/ContactsUpdater.h index d5e9dffbb..bfd6dcdab 100644 --- a/src/Contacts/ContactsUpdater.h +++ b/src/Contacts/ContactsUpdater.h @@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedUpdater; -- (SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error; +- (nullable SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error; - (void)lookupIdentifier:(NSString *)identifier success:(void (^)(NSSet *matchedIds))success diff --git a/src/Contacts/ContactsUpdater.m b/src/Contacts/ContactsUpdater.m index ec9639503..d3d95d07f 100644 --- a/src/Contacts/ContactsUpdater.m +++ b/src/Contacts/ContactsUpdater.m @@ -24,26 +24,32 @@ NS_ASSUME_NONNULL_BEGIN return sharedInstance; } -- (SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error +- (nullable SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error { dispatch_semaphore_t sema = dispatch_semaphore_create(0); __block SignalRecipient *recipient; + + // Assigning to a pointer parameter within the block is not preventing the referenced error from being dealloc + // Instead, we avoid ambiguity in ownership by assigning to a local __block variable ensuring the error will be + // retained until our error parameter can take ownership. + __block NSError *retainedError; [self lookupIdentifier:identifier success:^(NSSet *matchedIds) { if (matchedIds.count == 1) { recipient = [SignalRecipient recipientWithTextSecureIdentifier:identifier]; } else { - *error = [NSError errorWithDomain:@"contactsmanager.notfound" code:NOTFOUND_ERROR userInfo:nil]; + retainedError = [NSError errorWithDomain:@"contactsmanager.notfound" code:NOTFOUND_ERROR userInfo:nil]; } dispatch_semaphore_signal(sema); } - failure:^(NSError *blockerror) { - *error = blockerror; + failure:^(NSError *lookupError) { + retainedError = lookupError; dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + *error = retainedError; return recipient; } diff --git a/tests/TestSupport/Fakes/OWSFakeContactsUpdater.m b/tests/TestSupport/Fakes/OWSFakeContactsUpdater.m index a4997a019..6d56fdd3f 100644 --- a/tests/TestSupport/Fakes/OWSFakeContactsUpdater.m +++ b/tests/TestSupport/Fakes/OWSFakeContactsUpdater.m @@ -8,7 +8,7 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSFakeContactsUpdater -- (SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error +- (nullable SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error { NSLog(@"[OWSFakeContactsUpdater] Faking contact lookup."); return [[SignalRecipient alloc] initWithTextSecureIdentifier:@"fake-recipient-id" relay:nil supportsVoice:YES];