Skip to content

Commit 3c3fe79

Browse files
authored
Fix for issue where matchesshortlinkformat was returning true for all links. (#2563)
* Fix issue with matchesShortLinkFormat always returning true. * Fix style.
1 parent 6cd4f44 commit 3c3fe79

File tree

2 files changed

+106
-22
lines changed

2 files changed

+106
-22
lines changed

Example/DynamicLinks/Tests/FIRDynamicLinksTest.m

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ - (BOOL)setUpWithLaunchOptions:(nullable NSDictionary *)launchOptions
7777
clientID:(NSString *)clientID
7878
urlScheme:(nullable NSString *)urlScheme
7979
userDefaults:(nullable NSUserDefaults *)userDefaults;
80+
- (BOOL)canParseUniversalLinkURL:(nullable NSURL *)url;
8081
@end
8182

8283
@interface FakeShortLinkResolver : FIRDynamicLinkNetworking
@@ -774,13 +775,90 @@ - (void)testUniversalLinkWithSubdomain_DeepLinkWithParameters {
774775
XCTAssertEqualObjects(dynamicLink.url.absoluteString, parsedDeepLinkString);
775776
}
776777

777-
- (void)testMatchesUnversalLinkWithLongDurableLink {
778-
NSString *urlString =
779-
@"https://sample.page.link?link=https://google.com/test&ibi=com.google.sample&ius=79306483";
780-
NSURL *url = [NSURL URLWithString:urlString];
781-
BOOL matchesShort = [self.service matchesShortLinkFormat:url];
778+
- (void)testMatchesShortLinkFormat {
779+
NSArray<NSString *> *urlStrings =
780+
@[ @"https://test.app.goo.gl/xyz", @"https://test.app.goo.gl/xyz?link=" ];
781+
782+
for (NSString *urlString in urlStrings) {
783+
NSURL *url = [NSURL URLWithString:urlString];
784+
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
785+
786+
XCTAssertTrue(matchesShortLinkFormat,
787+
@"Non-DDL domain URL matched short link format with URL: %@", url);
788+
}
789+
}
790+
791+
// Custom domain entries in plist file:
792+
// https://google.com
793+
// https://google.com/one
794+
// https://a.firebase.com/mypath
795+
- (void)testFailMatchesShortLinkFormatForCustomDomains {
796+
NSArray<NSString *> *urlStrings = @[
797+
@"https://google.com",
798+
@"https://google.com?link=",
799+
@"https://a.firebase.com",
800+
@"https://a.firebase.com/mypath?link=",
801+
];
802+
803+
for (NSString *urlString in urlStrings) {
804+
NSURL *url = [NSURL URLWithString:urlString];
805+
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
806+
807+
XCTAssertFalse(matchesShortLinkFormat,
808+
@"Non-DDL domain URL matched short link format with URL: %@", url);
809+
}
810+
}
811+
812+
// Custom domain entries in plist file:
813+
// https://google.com
814+
// https://google.com/one
815+
// https://a.firebase.com/mypath
816+
- (void)testPassMatchesShortLinkFormatForCustomDomains {
817+
NSArray<NSString *> *urlStrings = @[
818+
@"https://google.com/xyz", @"https://google.com/xyz/?link=", @"https://google.com/xyz?link=",
819+
@"https://google.com/one/xyz", @"https://google.com/one/xyz?link=",
820+
@"https://google.com/one?utm_campaignlink=", @"https://google.com/mylink",
821+
@"https://google.com/one/mylink", @"https://a.firebase.com/mypath/mylink"
822+
];
823+
824+
for (NSString *urlString in urlStrings) {
825+
NSURL *url = [NSURL URLWithString:urlString];
826+
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
827+
828+
XCTAssertTrue(matchesShortLinkFormat,
829+
@"Non-DDL domain URL matched short link format with URL: %@", url);
830+
}
831+
}
782832

783-
XCTAssertFalse(matchesShort, @"Long Durable Link should not match short link format");
833+
- (void)testPassMatchesShortLinkFormat {
834+
NSArray<NSString *> *urlStrings = @[
835+
@"https://test.app.goo.gl/xyz",
836+
@"https://test.app.goo.gl/xyz?link=",
837+
];
838+
839+
for (NSString *urlString in urlStrings) {
840+
NSURL *url = [NSURL URLWithString:urlString];
841+
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
842+
843+
XCTAssertTrue(matchesShortLinkFormat,
844+
@"Non-DDL domain URL matched short link format with URL: %@", url);
845+
}
846+
}
847+
848+
- (void)testFailMatchesShortLinkFormat {
849+
NSArray<NSString *> *urlStrings = @[
850+
@"https://test.app.goo.gl", @"https://test.app.goo.gl?link=", @"https://test.app.goo.gl/",
851+
@"https://sample.page.link?link=https://google.com/test&ibi=com.google.sample&ius=79306483"
852+
@"https://sample.page.link/?link=https://google.com/test&ibi=com.google.sample&ius=79306483"
853+
];
854+
855+
for (NSString *urlString in urlStrings) {
856+
NSURL *url = [NSURL URLWithString:urlString];
857+
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
858+
859+
XCTAssertFalse(matchesShortLinkFormat,
860+
@"Non-DDL domain URL matched short link format with URL: %@", url);
861+
}
784862
}
785863

786864
- (void)testMatchesUnversalLinkWithShortDurableLink {
@@ -1073,19 +1151,26 @@ - (void)testValidCustomDomainNames {
10731151
NSArray<NSString *> *urlStrings = @[
10741152
@"https://google.com/mylink", // Short FDL starting with 'https://google.com'
10751153
@"https://google.com/one", // Short FDL starting with 'https://google.com'
1076-
@"https://google.com/?link=abcd", // Long FDL starting with 'https://google.com'
1077-
@"https://google.com/one/mylink", // Long FDL starting with 'https://google.com/one'
1154+
@"https://google.com/one/mylink", // Short FDL starting with 'https://google.com/one'
10781155
@"https://a.firebase.com/mypath/mylink", // Short FDL starting https://a.firebase.com/mypath
1156+
];
1157+
1158+
NSArray<NSString *> *longFDLURLStrings = @[
10791159
@"https://a.firebase.com/mypath/?link=abcd&test=1", // Long FDL starting with
10801160
// https://a.firebase.com/mypath
1161+
@"https://google.com/?link=abcd", // Long FDL starting with 'https://google.com'
10811162
];
1082-
10831163
for (NSString *urlString in urlStrings) {
10841164
NSURL *url = [NSURL URLWithString:urlString];
10851165
BOOL matchesShortLinkFormat = [self.service matchesShortLinkFormat:url];
10861166

1087-
XCTAssertTrue(matchesShortLinkFormat,
1088-
@"Non-DDL domain URL matched short link format with URL: %@", url);
1167+
XCTAssertTrue(matchesShortLinkFormat, @"URL did not validate as short link: %@", url);
1168+
}
1169+
for (NSString *urlString in longFDLURLStrings) {
1170+
NSURL *url = [NSURL URLWithString:urlString];
1171+
BOOL matchesLongLinkFormat = [self.service canParseUniversalLinkURL:url];
1172+
1173+
XCTAssertTrue(matchesLongLinkFormat, @"URL did not validate as long link: %@", url);
10891174
}
10901175
}
10911176

Firebase/DynamicLinks/Utilities/FDLUtilities.m

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,11 @@ BOOL FIRDLIsURLForWhiteListedCustomDomain(NSURL *_Nullable URL) {
211211
options:NSCaseInsensitiveSearch | NSAnchoredSearch]
212212
.location) == 0) {
213213
// The (short) URL needs to be longer than the domainURIPrefix, it's first character after
214-
// the domainURIPrefix needs to be '/' or '?' and should be followed by at-least one more
214+
// the domainURIPrefix needs to be '/' and should be followed by at-least one more
215215
// character.
216216
if (urlStr.length > domainURIPrefixStr.length + 1 &&
217-
([urlStr characterAtIndex:domainURIPrefixStr.length] == '/' ||
218-
[urlStr characterAtIndex:domainURIPrefixStr.length] == '?')) {
219-
// Check if there are any more '/' after the first '/' or '?' trailing the
217+
([urlStr characterAtIndex:domainURIPrefixStr.length] == '/')) {
218+
// Check if there are any more '/' after the first '/'trailing the
220219
// domainURIPrefix. This does not apply to unique match links copied from the clipboard.
221220
// The clipboard links will have '?link=' after the domainURIPrefix.
222221
NSString *urlWithoutDomainURIPrefix =
@@ -249,17 +248,17 @@ BOOL FIRDLCanParseUniversalLinkURL(NSURL *_Nullable URL) {
249248
}
250249

251250
BOOL FIRDLMatchesShortLinkFormat(NSURL *URL) {
252-
// Short Durable Link URLs always have a path, except for certain custom domain URLs e.g.
253-
// 'https://google.com?link=abcd' will not have a path component.
254-
// FIRDLIsURLForWhiteListedCustomDomain implicitely checks for path component in custom domain
255-
// URLs.
256-
BOOL hasPath = URL.path.length > 0 || FIRDLIsURLForWhiteListedCustomDomain(URL);
251+
// Short Durable Link URLs always have a path.
252+
BOOL hasPath = URL.path.length > 0;
253+
BOOL matchesRegularExpression =
254+
([URL.path rangeOfString:@"/[^/]+" options:NSRegularExpressionSearch].location != NSNotFound);
257255
// Must be able to parse (also checks if the URL conforms to *.app.goo.gl/* or goo.gl/app/*)
258-
BOOL canParse = FIRDLCanParseUniversalLinkURL(URL);
256+
BOOL canParse = FIRDLCanParseUniversalLinkURL(URL) | FIRDLIsURLForWhiteListedCustomDomain(URL);
257+
;
259258
// Path cannot be prefixed with /link/dismiss
260259
BOOL isDismiss = [[URL.path lowercaseString] hasPrefix:@"/link/dismiss"];
261260

262-
return hasPath && !isDismiss && canParse;
261+
return hasPath && matchesRegularExpression && !isDismiss && canParse;
263262
}
264263

265264
NSString *FIRDLMatchTypeStringFromServerString(NSString *_Nullable serverMatchTypeString) {

0 commit comments

Comments
 (0)