From d63a519c438c9f672acb394e8431da8801688a4f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 14 Mar 2017 09:58:27 -0300 Subject: [PATCH] Fix filtering of country codes in registration flow. // FREEBIE --- src/Contacts/PhoneNumberUtil.h | 5 +- src/Contacts/PhoneNumberUtil.m | 108 +++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/Contacts/PhoneNumberUtil.h b/src/Contacts/PhoneNumberUtil.h index 6761b1122..f0b4be643 100644 --- a/src/Contacts/PhoneNumberUtil.h +++ b/src/Contacts/PhoneNumberUtil.h @@ -1,3 +1,7 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + #import #import "NBPhoneNumberUtil.h" #import "PhoneNumber.h" @@ -9,7 +13,6 @@ + (NSString *)callingCodeFromCountryCode:(NSString *)code; + (NSString *)countryNameFromCountryCode:(NSString *)code; + (NSArray *)countryCodesForSearchTerm:(NSString *)searchTerm; -+ (NSArray *)validCountryCallingPrefixes:(NSString *)string; + (NSUInteger)translateCursorPosition:(NSUInteger)offset from:(NSString *)source diff --git a/src/Contacts/PhoneNumberUtil.m b/src/Contacts/PhoneNumberUtil.m index af5fcc9a4..f8b0dfb4d 100644 --- a/src/Contacts/PhoneNumberUtil.m +++ b/src/Contacts/PhoneNumberUtil.m @@ -38,60 +38,90 @@ } // country code -> calling code -+ (NSString *)callingCodeFromCountryCode:(NSString *)code { - NSNumber *callingCode = [[[self sharedUtil] nbPhoneNumberUtil] getCountryCodeForRegion:code]; - return [NSString stringWithFormat:@"%@%@", COUNTRY_CODE_PREFIX, callingCode]; ++ (NSString *)callingCodeFromCountryCode:(NSString *)countryCode +{ + if ([countryCode isEqualToString:@"AQ"]) { + // Antarctica + return @"+672"; + } else if ([countryCode isEqualToString:@"BV"]) { + // Bouvet Island + return @"+55"; + } else if ([countryCode isEqualToString:@"IC"]) { + // Canary Islands + return @"+34"; + } else if ([countryCode isEqualToString:@"EA"]) { + // Ceuta & Melilla + return @"+34"; + } else if ([countryCode isEqualToString:@"CP"]) { + // Clipperton Island + // + // This country code should be filtered - it does not appear to have a calling code. + return nil; + } else if ([countryCode isEqualToString:@"DG"]) { + // Diego Garcia + return @"+246"; + } else if ([countryCode isEqualToString:@"TF"]) { + // French Southern Territories + return @"+262"; + } else if ([countryCode isEqualToString:@"HM"]) { + // Heard & McDonald Islands + return @"+672"; + } else if ([countryCode isEqualToString:@"XK"]) { + // Kosovo + return @"+383"; + } else if ([countryCode isEqualToString:@"PN"]) { + // Pitcairn Islands + return @"+64"; + } else if ([countryCode isEqualToString:@"GS"]) { + // So. Georgia & So. Sandwich Isl. + return @"+500"; + } else if ([countryCode isEqualToString:@"UM"]) { + // U.S. Outlying Islands + return @"+1"; + } + + NSString *callingCode = [NSString stringWithFormat:@"%@%@", + COUNTRY_CODE_PREFIX, + [[[self sharedUtil] nbPhoneNumberUtil] getCountryCodeForRegion:countryCode]]; + return callingCode; } // search term -> country codes + (NSArray *)countryCodesForSearchTerm:(NSString *)searchTerm { + searchTerm = [searchTerm stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + NSArray *countryCodes = NSLocale.ISOCountryCodes; - if (searchTerm) { - countryCodes = [countryCodes filter:^int(NSString *code) { - NSString *countryName = [self countryNameFromCountryCode:code]; - NSString *callingCode = [self callingCodeFromCountryCode:code]; + if (searchTerm.length > 0) { + countryCodes = [countryCodes filter:^int(NSString *countryCode) { + NSString *countryName = [self countryNameFromCountryCode:countryCode]; + NSString *callingCode = [self callingCodeFromCountryCode:countryCode]; + + if (callingCode == nil || [callingCode isEqualToString:@"+0"]) { + // Filter out countries without a valid calling code. + return NO; + } - if ([[[TextSecureKitEnv sharedEnv].contactsManager class] name:countryName matchesQuery:searchTerm]) { - return YES; - } + if ([[[TextSecureKitEnv sharedEnv].contactsManager class] name:countryName matchesQuery:searchTerm]) { + return YES; + } + if ([[[TextSecureKitEnv sharedEnv].contactsManager class] name:countryCode matchesQuery:searchTerm]) { + return YES; + } - // We rely on the already internationalized string; as that is what - // the user would see entered (i.e. with COUNTRY_CODE_PREFIX). + // We rely on the already internationalized string; as that is what + // the user would see entered (i.e. with COUNTRY_CODE_PREFIX). - if ([callingCode containsString:searchTerm]) { - return YES; - } - return NO; + if ([callingCode containsString:searchTerm]) { + return YES; + } + return NO; }]; } return [self sortedCountryCodesByName:countryCodes]; } -+ (NSArray *)validCountryCallingPrefixes:(NSString *)string { - NSArray *countryCodes = NSLocale.ISOCountryCodes; - NSArray *matches = [countryCodes filter:^int(NSString *code) { - NSString *callingCode = [self callingCodeFromCountryCode:code]; - - return [string hasPrefix:callingCode]; - }]; - - return [matches sortedArrayWithOptions:NSSortConcurrent - usingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { - if (obj1 == nil) { - return obj2 ? NSOrderedAscending : NSOrderedSame; - } - - if (obj2 == nil) { - return NSOrderedDescending; - } - - NSInteger d = (NSInteger)[obj1 length] - (NSInteger)[obj2 length]; - return d ? (d < 0 ? NSOrderedAscending : NSOrderedDescending) : NSOrderedSame; - }]; -} - + (NSArray *)sortedCountryCodesByName:(NSArray *)countryCodesByISOCode { return [countryCodesByISOCode sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [[self countryNameFromCountryCode:obj1] caseInsensitiveCompare:[self countryNameFromCountryCode:obj2]];