From 8aa84b06bf048c7fb2d4f718a8dc4e910f96dee4 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Mon, 18 Oct 2021 15:19:57 -0400 Subject: [PATCH 1/3] Remove calls to LogInfo, LogError, LogDebug during obj-c +load. This could be causing an issue in C++ as global class constructors have not yet been run. --- app/src/util_ios.mm | 37 ++++++++++++++++++++++------------ messaging/src/ios/messaging.mm | 3 ++- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/app/src/util_ios.mm b/app/src/util_ios.mm index de2153c94f..476ab45253 100644 --- a/app/src/util_ios.mm +++ b/app/src/util_ios.mm @@ -102,8 +102,12 @@ void ForEachAppDelegateClass(void (^block)(Class)) { } } if (!blacklisted) { - ::firebase::LogDebug("Firebase: Found UIApplicationDelegate class %s", - class_name); + if (GetLogLevel() <= kLogLevelDebug) { + // Call NSLog directly because we may be in a +load method, + // and C++ classes may not be constructed yet. + NSLog(@"Firebase: Found UIApplicationDelegate class %s", + class_name); + } block(clazz); } } @@ -355,7 +359,9 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), FIREBASE_ASSERT(type_encoding); NSString *new_method_name_nsstring = nil; - ::firebase::LogDebug("Registering method for %s selector %s", class_name, selector_name); + if (GetLogLevel() <= kLogLevelDebug) { + NSLog(@"Registering method for %s selector %s", class_name, selector_name); + } if (original_method_implementation) { // Try adding a method with randomized prefix on the name. int retry = kRandomNameGenerationRetries; @@ -370,27 +376,32 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), } const char *new_method_name = new_method_name_nsstring.UTF8String; if (retry == 0) { - LogError("Failed to add method %s on class %s as the %s method already exists on the class. " - "To resolve this issue, change the name of the method %s on the class %s.", + NSLog(@"Failed to add method %s on class %s as the %s method already exists on the class. To resolve this issue, change the name of the method %s on the class %s.", new_method_name, class_name, new_method_name, new_method_name, class_name); return; } method_setImplementation(method, imp); // Save the selector name that points at the original method implementation. SetMethod(name, new_method_name_nsstring); - ::firebase::LogDebug("Registered method for %s selector %s (original method %s 0x%08x)", - class_name, selector_name, new_method_name, - static_cast(reinterpret_cast( - original_method_implementation))); + if (GetLogLevel() <= kLogLevelDebug) { + NSLog(@"Registered method for %s selector %s (original method %s 0x%08x)", + class_name, selector_name, new_method_name, + static_cast(reinterpret_cast( + original_method_implementation))); + } } else if (add_method) { - ::firebase::LogDebug("Adding method for %s selector %s", class_name, selector_name); + if (GetLogLevel() <= kLogLevelDebug) { + NSLog("Adding method for %s selector %s", class_name, selector_name); + } // The class doesn't implement the selector so simply install our method implementation. if (!class_addMethod(clazz, name, imp, type_encoding)) { - LogError("Failed to add new method %s on class %s.", selector_name, class_name); + NSLog(@"Failed to add new method %s on class %s.", selector_name, class_name); } } else { - ::firebase::LogDebug("Method implementation for %s selector %s not found, ignoring.", - class_name, selector_name); + if (GetLogLevel() <= kLogLevelDebug) { + NSLog(@"Method implementation for %s selector %s not found, ignoring.", + class_name, selector_name); + } } } diff --git a/messaging/src/ios/messaging.mm b/messaging/src/ios/messaging.mm index 934438faa4..fcf9f7cffe 100644 --- a/messaging/src/ios/messaging.mm +++ b/messaging/src/ios/messaging.mm @@ -869,7 +869,8 @@ void SetTokenRegistrationOnInitEnabled(bool enable) { // http://www.opensource.apple.com/source/objc4/objc4-274/runtime/objc-runtime.m) @implementation UIApplication (FIRFCM) + (void)load { - ::firebase::LogInfo("FCM: Loading UIApplication FIRFCM category"); + // C++ constructors may not be called yet so call NSLog rather than LogInfo. + NSLog(@"FCM: Loading UIApplication FIRFCM category"); ::firebase::util::ForEachAppDelegateClass(^(Class clazz) { FirebaseMessagingHookAppDelegate(clazz); }); From 90d5c2030fd4becff9fcc620ad4518aae1a72f82 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Mon, 18 Oct 2021 16:27:57 -0400 Subject: [PATCH 2/3] Fix NSLog call --- app/src/util_ios.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/util_ios.mm b/app/src/util_ios.mm index 476ab45253..3d796d6fd1 100644 --- a/app/src/util_ios.mm +++ b/app/src/util_ios.mm @@ -391,7 +391,7 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), } } else if (add_method) { if (GetLogLevel() <= kLogLevelDebug) { - NSLog("Adding method for %s selector %s", class_name, selector_name); + NSLog(@"Adding method for %s selector %s", class_name, selector_name); } // The class doesn't implement the selector so simply install our method implementation. if (!class_addMethod(clazz, name, imp, type_encoding)) { From 74557de122807cc9eebde6227494809e67525719 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Mon, 22 Nov 2021 14:00:17 -0800 Subject: [PATCH 3/3] Format code. --- app/src/util_ios.mm | 112 +++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 65 deletions(-) diff --git a/app/src/util_ios.mm b/app/src/util_ios.mm index 3d796d6fd1..265f9c8228 100644 --- a/app/src/util_ios.mm +++ b/app/src/util_ios.mm @@ -58,8 +58,7 @@ - (void)application:(UIApplication *)application } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo - fetchCompletionHandler: - (void (^)(UIBackgroundFetchResult result))handler { + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler { } #if defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0 - (BOOL)application:(UIApplication *)application @@ -74,7 +73,7 @@ - (BOOL)application:(UIApplication *)application restorationHandler:(void (^)(NSArray *))restorationHandler { return NO; } -#endif // defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0 +#endif // defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0 @end namespace firebase { @@ -103,11 +102,10 @@ void ForEachAppDelegateClass(void (^block)(Class)) { } if (!blacklisted) { if (GetLogLevel() <= kLogLevelDebug) { - // Call NSLog directly because we may be in a +load method, - // and C++ classes may not be constructed yet. - NSLog(@"Firebase: Found UIApplicationDelegate class %s", - class_name); - } + // Call NSLog directly because we may be in a +load method, + // and C++ classes may not be constructed yet. + NSLog(@"Firebase: Found UIApplicationDelegate class %s", class_name); + } block(clazz); } } @@ -115,8 +113,7 @@ void ForEachAppDelegateClass(void (^block)(Class)) { free(classes); } -NSDictionary *StringMapToNSDictionary( - const std::map &string_map) { +NSDictionary *StringMapToNSDictionary(const std::map &string_map) { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; for (auto &kv : string_map) { dictionary[[NSString stringWithUTF8String:kv.first.c_str()]] = @@ -125,8 +122,7 @@ void ForEachAppDelegateClass(void (^block)(Class)) { return dictionary; } -NSDictionary *CharArrayMapToNSDictionary( - const std::map &string_map) { +NSDictionary *CharArrayMapToNSDictionary(const std::map &string_map) { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; for (auto &kv : string_map) { dictionary[[NSString stringWithUTF8String:kv.first]] = @@ -147,17 +143,14 @@ void ForEachAppDelegateClass(void (^block)(Class)) { return std::string(static_cast(data.bytes), data.length); } -NSString *StringToNSString(const std::string &str) { - return CStringToNSString(str.c_str()); -} +NSString *StringToNSString(const std::string &str) { return CStringToNSString(str.c_str()); } NSString *CStringToNSString(const char *c_str) { return [NSString stringWithCString:c_str encoding:NSUTF8StringEncoding]; } std::string NSStringToString(NSString *str) { - return str ? std::string([str cStringUsingEncoding:NSUTF8StringEncoding]) : - std::string(); + return str ? std::string([str cStringUsingEncoding:NSUTF8StringEncoding]) : std::string(); } NSMutableArray *StringVectorToNSMutableArray(const std::vector &vector) { @@ -168,41 +161,37 @@ void ForEachAppDelegateClass(void (^block)(Class)) { return array; } -NSMutableArray* StdVectorToNSMutableArray(const std::vector& vector) { - NSMutableArray* array = - [[NSMutableArray alloc] initWithCapacity:vector.size()]; - for (auto& variant : vector) { +NSMutableArray *StdVectorToNSMutableArray(const std::vector &vector) { + NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:vector.size()]; + for (auto &variant : vector) { [array addObject:VariantToId(variant)]; } return array; } -NSMutableDictionary* StdMapToNSMutableDictionary( - const std::map& map) { - NSMutableDictionary* dictionary = - [[NSMutableDictionary alloc] initWithCapacity:map.size()]; - for (auto& pair : map) { - [dictionary setObject:VariantToId(pair.second) - forKey:VariantToId(pair.first)]; +NSMutableDictionary *StdMapToNSMutableDictionary(const std::map &map) { + NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:map.size()]; + for (auto &pair : map) { + [dictionary setObject:VariantToId(pair.second) forKey:VariantToId(pair.first)]; } return dictionary; } -void NSArrayToStdVector(NSArray *array, std::vector* vector) { +void NSArrayToStdVector(NSArray *array, std::vector *vector) { vector->reserve(array.count); for (id object in array) { vector->push_back(IdToVariant(object)); } } -void NSDictionaryToStdMap(NSDictionary *dictionary, std::map* map) { +void NSDictionaryToStdMap(NSDictionary *dictionary, std::map *map) { for (id key in dictionary) { id value = [dictionary objectForKey:key]; map->insert(std::make_pair(IdToVariant(key), IdToVariant(value))); } } -id VariantToId(const Variant& variant) { +id VariantToId(const Variant &variant) { switch (variant.type()) { case Variant::kTypeNull: { return [NSNull null]; @@ -235,22 +224,18 @@ id VariantToId(const Variant& variant) { static bool IdIsBoolean(id value) { if ([value isKindOfClass:[NSNumber class]]) { - const char* type = [value objCType]; - return strcmp(type, @encode(BOOL)) == 0 || - strcmp(type, @encode(signed char)) == 0; + const char *type = [value objCType]; + return strcmp(type, @encode(BOOL)) == 0 || strcmp(type, @encode(signed char)) == 0; } return false; } static bool IdIsInteger(id value) { if ([value isKindOfClass:[NSNumber class]]) { - const char* type = [value objCType]; - return strcmp(type, @encode(int)) == 0 || - strcmp(type, @encode(short)) == 0 || - strcmp(type, @encode(long)) == 0 || - strcmp(type, @encode(long long)) == 0 || - strcmp(type, @encode(unsigned char)) == 0 || - strcmp(type, @encode(unsigned int)) == 0 || + const char *type = [value objCType]; + return strcmp(type, @encode(int)) == 0 || strcmp(type, @encode(short)) == 0 || + strcmp(type, @encode(long)) == 0 || strcmp(type, @encode(long long)) == 0 || + strcmp(type, @encode(unsigned char)) == 0 || strcmp(type, @encode(unsigned int)) == 0 || strcmp(type, @encode(unsigned short)) == 0 || strcmp(type, @encode(unsigned long)) == 0 || strcmp(type, @encode(unsigned long long)) == 0; @@ -260,9 +245,8 @@ static bool IdIsInteger(id value) { static bool IdIsFloatingPoint(id value) { if ([value isKindOfClass:[NSNumber class]]) { - const char* type = [value objCType]; - return strcmp(type, @encode(float)) == 0 || - strcmp(type, @encode(double)) == 0; + const char *type = [value objCType]; + return strcmp(type, @encode(float)) == 0 || strcmp(type, @encode(double)) == 0; } return false; } @@ -311,15 +295,13 @@ void DispatchAsyncSafeMainQueue(void (^block)(void)) { } } -void RunOnMainThread(void (*function_ptr)(void *function_data), - void *function_data) { +void RunOnMainThread(void (*function_ptr)(void *function_data), void *function_data) { dispatch_async(dispatch_get_main_queue(), ^{ function_ptr(function_data); }); } -void RunOnBackgroundThread(void (*function_ptr)(void *function_data), - void *function_data) { +void RunOnBackgroundThread(void (*function_ptr)(void *function_data), void *function_data) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ function_ptr(function_data); }); @@ -354,8 +336,8 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), // Get the type encoding of the selector from a type_encoding_class (which is a class which // implements a stub for the method). - const char *type_encoding = method_getTypeEncoding( - class_getInstanceMethod(type_encoding_class, name)); + const char *type_encoding = + method_getTypeEncoding(class_getInstanceMethod(type_encoding_class, name)); FIREBASE_ASSERT(type_encoding); NSString *new_method_name_nsstring = nil; @@ -376,18 +358,18 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), } const char *new_method_name = new_method_name_nsstring.UTF8String; if (retry == 0) { - NSLog(@"Failed to add method %s on class %s as the %s method already exists on the class. To resolve this issue, change the name of the method %s on the class %s.", - new_method_name, class_name, new_method_name, new_method_name, class_name); + NSLog(@"Failed to add method %s on class %s as the %s method already exists on the class. To " + @"resolve this issue, change the name of the method %s on the class %s.", + new_method_name, class_name, new_method_name, new_method_name, class_name); return; } method_setImplementation(method, imp); // Save the selector name that points at the original method implementation. SetMethod(name, new_method_name_nsstring); if (GetLogLevel() <= kLogLevelDebug) { - NSLog(@"Registered method for %s selector %s (original method %s 0x%08x)", - class_name, selector_name, new_method_name, - static_cast(reinterpret_cast( - original_method_implementation))); + NSLog(@"Registered method for %s selector %s (original method %s 0x%08x)", class_name, + selector_name, new_method_name, + static_cast(reinterpret_cast(original_method_implementation))); } } else if (add_method) { if (GetLogLevel() <= kLogLevelDebug) { @@ -399,8 +381,8 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), } } else { if (GetLogLevel() <= kLogLevelDebug) { - NSLog(@"Method implementation for %s selector %s not found, ignoring.", - class_name, selector_name); + NSLog(@"Method implementation for %s selector %s not found, ignoring.", class_name, + selector_name); } } } @@ -431,10 +413,10 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), const char *selector_implementation_name = selector_implementation_name_nsstring.UTF8String; SEL selector_implementation = NSSelectorFromString(selector_implementation_name_nsstring); search_class = clazz; - for ( ; search_class; search_class = class_getSuperclass(search_class)) { + for (; search_class; search_class = class_getSuperclass(search_class)) { const char *search_class_name = class_getName(search_class); - firebase::LogDebug("Searching for selector %s (%s) on class %s", - selector_name, selector_implementation_name, search_class_name); + firebase::LogDebug("Searching for selector %s (%s) on class %s", selector_name, + selector_implementation_name, search_class_name); Method method = class_getInstanceMethod(search_class, selector_implementation); method_implementation = method ? method_getImplementation(method) : nil; if (method_implementation) break; @@ -442,8 +424,8 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), if (method_implementation) break; } if (!method_implementation) { - firebase::LogDebug("Class %s does not respond to selector %s (%s)", class_name, - selector_name, selector_implementation_name_nsstring.UTF8String); + firebase::LogDebug("Class %s does not respond to selector %s (%s)", class_name, selector_name, + selector_implementation_name_nsstring.UTF8String); return nil; } firebase::LogDebug("Found %s (%s, 0x%08x) on class %s (%s)", selector_name, @@ -483,8 +465,8 @@ void RunOnBackgroundThread(void (*function_ptr)(void *function_data), while (retry--) { // Cache the old method implementation in a new method so that we can lookup the original // implementation from the instance of the class. - NSString *random_selector_name = [[NSString alloc] initWithFormat:@"FIRA%x%@", arc4random(), - selector_name]; + NSString *random_selector_name = + [[NSString alloc] initWithFormat:@"FIRA%x%@", arc4random(), selector_name]; if (!implementation_selector_names[random_selector_name]) { return random_selector_name; }