Skip to content

Commit e53d552

Browse files
Allow Bundle IDs that have a valid prefix - strict validation (#2515)
Allow Bundle IDs that have a valid prefix - strict validation
1 parent 1363332 commit e53d552

File tree

5 files changed

+67
-9
lines changed

5 files changed

+67
-9
lines changed

Example/Core/Tests/FIRBundleUtilTest.m

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import "FIRTestCase.h"
1616

1717
#import <FirebaseCore/FIRBundleUtil.h>
18+
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
1819

1920
static NSString *const kResultPath = @"resultPath";
2021
static NSString *const kResourceName = @"resourceName";
@@ -69,16 +70,53 @@ - (void)testFindOptionsDictionaryPath_secondBundle {
6970
- (void)testBundleIdentifierExistsInBundles {
7071
NSString *bundleID = @"com.google.test";
7172
[OCMStub([self.mockBundle bundleIdentifier]) andReturn:bundleID];
72-
XCTAssertTrue([FIRBundleUtil hasBundleIdentifier:bundleID inBundles:@[ self.mockBundle ]]);
73+
XCTAssertTrue([FIRBundleUtil hasBundleIdentifierPrefix:bundleID inBundles:@[ self.mockBundle ]]);
7374
}
7475

7576
- (void)testBundleIdentifierExistsInBundles_notExist {
7677
[OCMStub([self.mockBundle bundleIdentifier]) andReturn:@"com.google.test"];
77-
XCTAssertFalse([FIRBundleUtil hasBundleIdentifier:@"not-exist" inBundles:@[ self.mockBundle ]]);
78+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"not-exist"
79+
inBundles:@[ self.mockBundle ]]);
7880
}
7981

8082
- (void)testBundleIdentifierExistsInBundles_emptyBundlesArray {
81-
XCTAssertFalse([FIRBundleUtil hasBundleIdentifier:@"com.google.test" inBundles:@[]]);
83+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.test" inBundles:@[]]);
84+
}
85+
86+
- (void)testBundleIdentifierHasPrefixInBundlesForExtension {
87+
id environmentUtilsMock = [OCMockObject mockForClass:[GULAppEnvironmentUtil class]];
88+
[[[environmentUtilsMock stub] andReturnValue:@(YES)] isAppExtension];
89+
90+
[OCMStub([self.mockBundle bundleIdentifier]) andReturn:@"com.google.test"];
91+
XCTAssertTrue([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.test.someextension"
92+
inBundles:@[ self.mockBundle ]]);
93+
94+
[environmentUtilsMock stopMocking];
95+
}
96+
97+
- (void)testBundleIdentifierHasPrefixInBundlesNotValidExtension {
98+
id environmentUtilsMock = [OCMockObject mockForClass:[GULAppEnvironmentUtil class]];
99+
[[[environmentUtilsMock stub] andReturnValue:@(YES)] isAppExtension];
100+
101+
[OCMStub([self.mockBundle bundleIdentifier]) andReturn:@"com.google.test"];
102+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.test.someextension.some"
103+
inBundles:@[ self.mockBundle ]]);
104+
105+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.testsomeextension"
106+
inBundles:@[ self.mockBundle ]]);
107+
108+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.testsomeextension.some"
109+
inBundles:@[ self.mockBundle ]]);
110+
111+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"not-exist"
112+
inBundles:@[ self.mockBundle ]]);
113+
114+
// Should be NO, since if @"com.google.tests" is an app extension identifier, then the app bundle
115+
// identifier is @"com.google"
116+
XCTAssertFalse([FIRBundleUtil hasBundleIdentifierPrefix:@"com.google.tests"
117+
inBundles:@[ self.mockBundle ]]);
118+
119+
[environmentUtilsMock stopMocking];
82120
}
83121

84122
@end

Firebase/Core/FIRApp.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,8 @@ - (void)checkExpectedBundleID {
525525
NSString *expectedBundleID = [self expectedBundleID];
526526
// The checking is only done when the bundle ID is provided in the serviceInfo dictionary for
527527
// backward compatibility.
528-
if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifier:expectedBundleID
529-
inBundles:bundles]) {
528+
if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifierPrefix:expectedBundleID
529+
inBundles:bundles]) {
530530
FIRLogError(kFIRLoggerCore, @"I-COR000008",
531531
@"The project's Bundle ID is inconsistent with "
532532
@"either the Bundle ID in '%@.%@', or the Bundle ID in the options if you are "

Firebase/Core/FIRBundleUtil.m

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#import "Private/FIRBundleUtil.h"
1616

17+
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
18+
1719
@implementation FIRBundleUtil
1820

1921
+ (NSArray *)relevantBundles {
@@ -45,13 +47,29 @@ + (NSArray *)relevantURLSchemes {
4547
return result;
4648
}
4749

48-
+ (BOOL)hasBundleIdentifier:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles {
50+
+ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles {
4951
for (NSBundle *bundle in bundles) {
50-
if ([bundle.bundleIdentifier isEqualToString:bundleIdentifier]) {
52+
// This allows app extensions that have the app's bundle as their prefix to pass this test.
53+
NSString *applicationBundleIdentifier =
54+
[GULAppEnvironmentUtil isAppExtension]
55+
? [self bundleIdentifierByRemovingLastPartFrom:bundleIdentifier]
56+
: bundleIdentifier;
57+
58+
if ([applicationBundleIdentifier isEqualToString:bundle.bundleIdentifier]) {
5159
return YES;
5260
}
5361
}
5462
return NO;
5563
}
5664

65+
+ (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier {
66+
NSString *bundleIDComponentsSeparator = @".";
67+
68+
NSMutableArray<NSString *> *bundleIDComponents =
69+
[[bundleIdentifier componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy];
70+
[bundleIDComponents removeLastObject];
71+
72+
return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator];
73+
}
74+
5775
@end

Firebase/Core/Private/FIRBundleUtil.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@
4545
+ (NSArray *)relevantURLSchemes;
4646

4747
/**
48-
* Checks if the bundle identifier exists in the given bundles.
48+
* Checks if any of the given bundles have a matching bundle identifier prefix (removing extension
49+
* suffixes).
4950
*/
50-
+ (BOOL)hasBundleIdentifier:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles;
51+
+ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles;
5152

5253
@end

FirebaseCore.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Firebase Core includes FIRApp and FIROptions which provide central configuration
2828
s.public_header_files = 'Firebase/Core/Public/*.h', 'Firebase/Core/Private/*.h'
2929
s.private_header_files = 'Firebase/Core/Private/*.h'
3030
s.framework = 'Foundation'
31+
s.dependency 'GoogleUtilities/Environment', '~> 5.2'
3132
s.dependency 'GoogleUtilities/Logger', '~> 5.2'
3233
s.pod_target_xcconfig = {
3334
'GCC_C_LANGUAGE_STANDARD' => 'c99',

0 commit comments

Comments
 (0)