@@ -575,33 +575,32 @@ + (BOOL)validateAppID:(NSString *)appID {
575
575
return NO ;
576
576
}
577
577
578
- // All app IDs must start with at least "<version number>:".
579
- NSString *const versionPattern = @" ^\\ d+:" ;
580
- NSRegularExpression *versionRegex =
581
- [NSRegularExpression regularExpressionWithPattern: versionPattern options: 0 error: NULL ];
582
- if (!versionRegex) {
578
+ NSScanner *stringScanner = [NSScanner scannerWithString: appID];
579
+ stringScanner.charactersToBeSkipped = nil ;
580
+
581
+ NSString *appIDVersion;
582
+ if (![stringScanner scanCharactersFromSet: [NSCharacterSet decimalDigitCharacterSet ]
583
+ intoString: &appIDVersion]) {
583
584
return NO ;
584
585
}
585
586
586
- NSRange appIDRange = NSMakeRange (0 , appID.length );
587
- NSArray *versionMatches = [versionRegex matchesInString: appID options: 0 range: appIDRange];
588
- if (versionMatches.count != 1 ) {
587
+ if (![stringScanner scanString: @" :" intoString: NULL ]) {
588
+ // appIDVersion must be separated by ":"
589
589
return NO ;
590
590
}
591
591
592
- NSRange versionRange = [(NSTextCheckingResult *)versionMatches.firstObject range ];
593
- NSString *appIDVersion = [appID substringWithRange: versionRange];
594
- NSArray *knownVersions = @[ @" 1:" ];
592
+ NSArray *knownVersions = @[ @" 1" ];
595
593
if (![knownVersions containsObject: appIDVersion]) {
596
594
// Permit unknown yet properly formatted app ID versions.
595
+ FIRLogInfo (kFIRLoggerCore , @" I-COR000010" , @" Unknown GOOGLE_APP_ID version: %@ " , appIDVersion);
597
596
return YES ;
598
597
}
599
598
600
- if (![FIRApp validateAppIDFormat: appID withVersion: appIDVersion]) {
599
+ if (![self validateAppIDFormat: appID withVersion: appIDVersion]) {
601
600
return NO ;
602
601
}
603
602
604
- if (![FIRApp validateAppIDFingerprint: appID withVersion: appIDVersion]) {
603
+ if (![self validateAppIDFingerprint: appID withVersion: appIDVersion]) {
605
604
return NO ;
606
605
}
607
606
@@ -631,33 +630,76 @@ + (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version {
631
630
return NO ;
632
631
}
633
632
634
- if (![version hasSuffix: @" :" ]) {
633
+ NSScanner *stringScanner = [NSScanner scannerWithString: appID];
634
+ stringScanner.charactersToBeSkipped = nil ;
635
+
636
+ // Skip version part
637
+ // '*<version #>*:<project number>:ios:<fingerprint of bundle id>'
638
+ if (![stringScanner scanString: version intoString: NULL ]) {
639
+ // The version part is missing or mismatched
640
+ return NO ;
641
+ }
642
+
643
+ // Validate version part (see part between '*' symbols below)
644
+ // '<version #>*:*<project number>:ios:<fingerprint of bundle id>'
645
+ if (![stringScanner scanString: @" :" intoString: NULL ]) {
646
+ // appIDVersion must be separated by ":"
647
+ return NO ;
648
+ }
649
+
650
+ // Validate version part (see part between '*' symbols below)
651
+ // '<version #>:*<project number>*:ios:<fingerprint of bundle id>'.
652
+ NSInteger projectNumber = NSNotFound ;
653
+ if (![stringScanner scanInteger: &projectNumber]) {
654
+ // NO project number found.
655
+ return NO ;
656
+ }
657
+
658
+ // Validate version part (see part between '*' symbols below)
659
+ // '<version #>:<project number>*:*ios:<fingerprint of bundle id>'.
660
+ if (![stringScanner scanString: @" :" intoString: NULL ]) {
661
+ // The project number must be separated by ":"
662
+ return NO ;
663
+ }
664
+
665
+ // Validate version part (see part between '*' symbols below)
666
+ // '<version #>:<project number>:*ios*:<fingerprint of bundle id>'.
667
+ NSString *platform;
668
+ if (![stringScanner scanUpToString: @" :" intoString: &platform]) {
635
669
return NO ;
636
670
}
637
671
638
- if (![appID hasPrefix: version]) {
672
+ if (![platform isEqualToString: @" ios" ]) {
673
+ // The platform must be @"ios"
639
674
return NO ;
640
675
}
641
676
642
- NSString *const pattern = @" ^\\ d+:ios:[a-f0-9]+$" ;
643
- NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: pattern
644
- options: 0
645
- error: NULL ];
646
- if (!regex) {
677
+ // Validate version part (see part between '*' symbols below)
678
+ // '<version #>:<project number>:ios*:*<fingerprint of bundle id>'.
679
+ if (![stringScanner scanString: @" :" intoString: NULL ]) {
680
+ // The platform must be separated by ":"
647
681
return NO ;
648
682
}
649
683
650
- NSRange localRange = NSMakeRange (version.length , appID.length - version.length );
651
- NSUInteger numberOfMatches = [regex numberOfMatchesInString: appID options: 0 range: localRange];
652
- if (numberOfMatches != 1 ) {
684
+ // Validate version part (see part between '*' symbols below)
685
+ // '<version #>:<project number>:ios:*<fingerprint of bundle id>*'.
686
+ unsigned long long fingerprint = NSNotFound ;
687
+ if (![stringScanner scanHexLongLong: &fingerprint]) {
688
+ // Fingerprint part is missing
653
689
return NO ;
654
690
}
691
+
692
+ if (!stringScanner.isAtEnd ) {
693
+ // There are not allowed characters in the fingerprint part
694
+ return NO ;
695
+ }
696
+
655
697
return YES ;
656
698
}
657
699
658
700
/* *
659
701
* Validates that the fingerprint of the app ID string is what is expected based on the supplied
660
- * version. The version must end in ":".
702
+ * version.
661
703
*
662
704
* Note that the v1 hash algorithm is not permitted on the client and cannot be fully validated.
663
705
*
@@ -667,18 +709,6 @@ + (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version {
667
709
* otherwise.
668
710
*/
669
711
+ (BOOL )validateAppIDFingerprint : (NSString *)appID withVersion : (NSString *)version {
670
- if (!appID.length || !version.length ) {
671
- return NO ;
672
- }
673
-
674
- if (![version hasSuffix: @" :" ]) {
675
- return NO ;
676
- }
677
-
678
- if (![appID hasPrefix: version]) {
679
- return NO ;
680
- }
681
-
682
712
// Extract the supplied fingerprint from the supplied app ID.
683
713
// This assumes the app ID format is the same for all known versions below. If the app ID format
684
714
// changes in future versions, the tokenizing of the app ID format will need to take into account
@@ -699,7 +729,7 @@ + (BOOL)validateAppIDFingerprint:(NSString *)appID withVersion:(NSString *)versi
699
729
return NO ;
700
730
}
701
731
702
- if ([version isEqual: @" 1: " ]) {
732
+ if ([version isEqual: @" 1" ]) {
703
733
// The v1 hash algorithm is not permitted on the client so the actual hash cannot be validated.
704
734
return YES ;
705
735
}
0 commit comments