Ver código fonte

Fdl unit tests (#9516)

 Refactoring custom domain validation logic with fixes and adding new unit tests.
Eldhose M Babu 4 anos atrás
pai
commit
c1a33a099d

+ 3 - 0
FirebaseDynamicLinks/CHANGELOG.md

@@ -1,3 +1,6 @@
+# v8.15.0
+- [fixed] Fixed Custom domain long url validation logic. (#6978)
+
 # v8.9.0
 - [fixed] Fixed Shortlink regression involving underscores and dashes introduced in 8.8.0. (#8786)
 - [fixed] Reduce memory stress on `WebKit` API. (#8847)

+ 36 - 27
FirebaseDynamicLinks/Sources/Utilities/FDLUtilities.m

@@ -201,37 +201,46 @@ NSString *FIRDLDeviceTimezone() {
   return timeZoneName;
 }
 
-BOOL FIRDLIsURLForAllowedCustomDomain(NSURL *_Nullable URL) {
-  BOOL customDomainMatchFound = false;
-  for (NSURL *allowedCustomDomain in FIRDLCustomDomains) {
-    // At least one custom domain host name should match at a minimum.
-    if ([allowedCustomDomain.host isEqualToString:URL.host]) {
-      NSString *urlStr = URL.absoluteString;
-      NSString *domainURIPrefixStr = allowedCustomDomain.absoluteString;
-
-      // Next, do a string compare to check if entire domainURIPrefix matches as well.
-      if (([urlStr rangeOfString:domainURIPrefixStr
-                         options:NSCaseInsensitiveSearch | NSAnchoredSearch]
-               .location) == 0) {
-        NSString *urlWithoutDomainURIPrefix = [urlStr substringFromIndex:domainURIPrefixStr.length];
-
-        // For a valid custom domain DL Suffix:
-        // 1. At least one path exists OR
-        // 2. Should have a link query param with an http/https link
-        BOOL matchesRegularExpression =
-            ([urlWithoutDomainURIPrefix
-                 rangeOfString:@"((\\/[A-Za-z0-9]+)|((\\?|\\/\\?)link=https?.*))"
-                       options:NSRegularExpressionSearch]
-                 .location != NSNotFound);
-
-        if (matchesRegularExpression) {
-          customDomainMatchFound = true;
-          break;
+BOOL FIRDLIsURLForAllowedCustomDomain(NSURL *URL) {
+  if (URL) {
+    for (NSURL *allowedCustomDomain in FIRDLCustomDomains) {
+      // At least one custom domain host name should match at a minimum.
+      if ([URL.absoluteString hasPrefix:allowedCustomDomain.absoluteString]) {
+        NSString *urlWithoutDomainURIPrefix =
+            [URL.absoluteString substringFromIndex:allowedCustomDomain.absoluteString.length];
+
+        // The urlWithoutDomainURIPrefix should be starting with '/' or '?' otherwise it means the
+        // allowed domain is not exactly matching the incoming URL domain prefix.
+        if ([urlWithoutDomainURIPrefix hasPrefix:@"/"] ||
+            [urlWithoutDomainURIPrefix hasPrefix:@"?"]) {
+          //  For a valid custom domain DL Suffix the urlWithoutDomainURIPrefix should have:
+          //  1. At least one path exists OR
+          //  2. Should have a link query param with an http/https link
+
+          NSURLComponents *components =
+              [[NSURLComponents alloc] initWithString:urlWithoutDomainURIPrefix];
+          if (components.path && components.path.length > 1) {
+            // Have a path exists. So valid custom domain.
+            return true;
+          }
+
+          if (components.queryItems && components.queryItems.count > 0) {
+            for (NSURLQueryItem *queryItem in components.queryItems) {
+              // Checks whether we have a link query param
+              if ([queryItem.name caseInsensitiveCompare:@"link"] == NSOrderedSame) {
+                // Checks whether link query param value starts with http/https
+                if (queryItem.value && ([queryItem.value hasPrefix:@"http://"] ||
+                                        [queryItem.value hasPrefix:@"https://"])) {
+                  return true;
+                }
+              }
+            }
+          }
         }
       }
     }
   }
-  return customDomainMatchFound;
+  return false;
 }
 
 /* We are validating following domains in proper format.

+ 21 - 4
FirebaseDynamicLinks/Tests/Unit/FIRDynamicLinksTest.m

@@ -1625,8 +1625,10 @@ static NSString *const kInfoPlistCustomDomainsKey = @"FirebaseDynamicLinksCustom
                                                               // argument.
     @"https://google.com/?some=qry&link=https://somedomain",  // Long FDL with link param as second
                                                               // argument
-    @"https://google.com/?a=b&c=d&link=https://somedomain&y=z",  // Long FDL with link param as
-                                                                 // middle argument argument
+    @"https://google.com/?a=b&c=d&link=https://somedomain&y=z",    // Long FDL with link param as
+                                                                   // middle argument argument
+    @"https://google.com?some=qry&link=https%3A%2F%2Fsomedomain",  // Long FDL with Url encoded link
+                                                                   // param
   ];
   for (NSString *urlString in urlStrings) {
     NSURL *url = [NSURL URLWithString:urlString];
@@ -1661,12 +1663,27 @@ static NSString *const kInfoPlistCustomDomainsKey = @"FirebaseDynamicLinksCustom
     @"mydomain.com",                           // https scheme not specified for domainURIPrefix.
     @"http://mydomain",  // Domain not in plist. No path after domainURIPrefix.
     @"https://somecustom.com?", @"https://somecustom.com/?",
-    @"https://somecustom.com?somekey=someval"
+    @"https://somecustom.com?somekey=someval",
+    @"https://google.com?some=qry&somelink=https%3A%2F%2Fsomedomain",  // Having somelink param
+                                                                       // instead of link param to
+                                                                       // confuse validation.
+    @"https://a.firebase.com/mypaths?some=qry&link=https%3A%2F%2Fsomedomain",  // Additional 's' in
+                                                                               // path param
+    @"https://a.firebase.com/mypath/?some=qry#other=b&link=https://somedomain",  // link param comes
+                                                                                 // in fragmentation
+    @"https://a.firebase.com/mypath/?some=qry#other=b&link=https%3A%2F%2Fsomedomain",  // link param
+                                                                                       // which is
+                                                                                       // url
+                                                                                       // encoded
+                                                                                       // and comes
+                                                                                       // in
+                                                                                       // fragmentation.
+    @"https://google.com?link=https1://abcd",  // link query param is not a valid http link
   ];
 
   for (NSString *urlString in urlStrings) {
     NSURL *url = [NSURL URLWithString:urlString];
-    BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
+    BOOL matchesShortLinkFormat = [self.service canParseUniversalLinkURL:url];
 
     XCTAssertFalse(matchesShortLinkFormat,
                    @"Non-DDL domain URL matched short link format with URL: %@", url);