From 58339b7c778895b29cb567b72be224667b549d01 Mon Sep 17 00:00:00 2001 From: sid-j <7937756+j-sid@users.noreply.github.com> Date: Wed, 28 Jul 2021 14:51:33 -0700 Subject: [PATCH] Changed Analytics to use SHA256 from MD5 since MD5 has been deprecated from iOS 13. Bumped podspec version. --- Classes/GTXAnalyticsUtils.h | 5 +++ Classes/GTXAnalyticsUtils.m | 42 ++++++++++++-------- GTXiLib.podspec | 6 +-- Tests/GTXTests/UnitTests/GTXAnalyticsTests.m | 7 ++++ 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Classes/GTXAnalyticsUtils.h b/Classes/GTXAnalyticsUtils.h index 864318a..7394d07 100644 --- a/Classes/GTXAnalyticsUtils.h +++ b/Classes/GTXAnalyticsUtils.h @@ -43,6 +43,11 @@ NS_ASSUME_NONNULL_BEGIN */ + (NSString *)clientID; +/** + @return An appropriate clientID for analytics that is based on hash of given @c bundleID. + */ ++ (NSString *)clientIDForBundleID:(NSString *)bundleID; + @end NS_ASSUME_NONNULL_END diff --git a/Classes/GTXAnalyticsUtils.m b/Classes/GTXAnalyticsUtils.m index cb16b33..84a0d44 100644 --- a/Classes/GTXAnalyticsUtils.m +++ b/Classes/GTXAnalyticsUtils.m @@ -15,6 +15,7 @@ // #import "GTXAnalyticsUtils.h" +#import "GTXAssertions.h" #import "GTXLogging.h" #import @@ -28,30 +29,37 @@ @implementation GTXAnalyticsUtils -/** - @return The clientID to be used by GTXiLib analytics, this is a hash of App's bundle ID. - */ ++ (NSString *)clientIDForBundleID:(NSString *)bundleID { + // Get SHA256 value of the given string. + unsigned char sha256Value[CC_SHA256_DIGEST_LENGTH]; + const char *stringCPtr = [bundleID UTF8String]; + CC_SHA256(stringCPtr, (CC_LONG)strlen(stringCPtr), sha256Value); + + // Parse SHA256 value into individual hex values. Note that Google Analytics client ID must be + // 128bits long, but SHA256 is 256 bits and there is no standard way to compress hashes, in our + // case we use bitwise XOR of the two 128 bit hashes inside the 256 bit hash to produce a 128bit + // hash. + NSMutableString *stringWithHexValues = [[NSMutableString alloc] init]; + const NSInteger kClientIDSize = 16; + GTX_ASSERT(kClientIDSize * 2 == CC_SHA256_DIGEST_LENGTH, + @"CC_SHA256_DIGEST_LENGTH must be 32 it was %d", (int)CC_SHA256_DIGEST_LENGTH); + for (int i = 0; i < kClientIDSize; i++) { + [stringWithHexValues appendFormat:@"%02x", sha256Value[i] ^ sha256Value[kClientIDSize + i]]; + } + return stringWithHexValues; +} + + (NSString *)clientID { static NSString *clientID; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *bundleIDMD5 = [[NSBundle mainBundle] bundleIdentifier]; - if (!bundleIDMD5) { + NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; + if (!bundleID) { // If bundle ID is not available we use a placeholder. - bundleIDMD5 = @""; + bundleID = @""; } - // Get MD5 value of the given string. - unsigned char md5Value[CC_MD5_DIGEST_LENGTH]; - const char *stringCPtr = [bundleIDMD5 UTF8String]; - CC_MD5(stringCPtr, (CC_LONG)strlen(stringCPtr), md5Value); - - // Parse MD5 value into individual hex values. - NSMutableString *stringWithHexMd5Values = [[NSMutableString alloc] init]; - for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { - [stringWithHexMd5Values appendFormat:@"%02x", md5Value[i]]; - } - clientID = [stringWithHexMd5Values copy]; + clientID = [self clientIDForBundleID:bundleID]; }); return clientID; diff --git a/GTXiLib.podspec b/GTXiLib.podspec index f30cb28..1442d7e 100644 --- a/GTXiLib.podspec +++ b/GTXiLib.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "GTXiLib" - s.version = "4.4" + s.version = "4.5" s.summary = "iOS Accessibility testing library." s.description = <<-DESC iOS Accessibility testing library that works with XCTest based frameworks. @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.license = "Apache License 2.0" s.author = "j-sid" s.platform = :ios - s.source = { :git => "https://github.com/google/GTXiLib.git", :tag => "4.4.0" } + s.source = { :git => "https://github.com/google/GTXiLib.git", :tag => "4.5.0" } s.source_files = "{Classes,OOPClasses}/**/*.{h,m,swift,mm,cc}" s.public_header_files = "Classes/**/*.h" s.private_header_files = [ @@ -22,4 +22,4 @@ Pod::Spec.new do |s| s.ios.deployment_target = '9.0' s.libraries = 'c++' s.dependency 'Protobuf-C++' -end \ No newline at end of file +end diff --git a/Tests/GTXTests/UnitTests/GTXAnalyticsTests.m b/Tests/GTXTests/UnitTests/GTXAnalyticsTests.m index ea0e4c7..6971d42 100644 --- a/Tests/GTXTests/UnitTests/GTXAnalyticsTests.m +++ b/Tests/GTXTests/UnitTests/GTXAnalyticsTests.m @@ -18,6 +18,7 @@ #import #import "GTXAnalytics.h" +#import "GTXAnalyticsUtils.h" #import "GTXToolKit.h" #import "GTXBaseTestCase.h" @@ -43,6 +44,12 @@ - (void)tearDown { [super tearDown]; } +- (void)testClientIDIsAccurate { + NSString *expectedClientID = @"90940a64d60ad6c98c3fb6c6307e1d36"; + XCTAssertEqualObjects(expectedClientID, + [GTXAnalyticsUtils clientIDForBundleID:@"com.google.gtx.test"]); +} + - (void)testCheckElementReportsAnalyticsCorrectly { GTXToolKit *toolkit = [GTXToolKit toolkitWithNoChecks]; __block NSInteger successEventsCount = 0;