Skip to content

Commit b259aac

Browse files
bentrengrovecopybara-github
authored andcommitted
[GH] [Navigation] Fix deeplink domain parsing being case sensitive
## Proposed Changes The current regex pattern matcher was doing a case sensitive check of the domain and arguments. Simply changing it to case insensitive seems to be all that's required to fix this bug. It is important that parameters are still case sensitive but this is still the case as parameter matching is done by the `Uri` code not the `NavDeepLink` code. I have written tests to cover these cases. If it is deemed too risky to just run the pattern matcher with `CASE_INSENSITIVE` I believe the regex will have to be redesigned not to use `\Q\E`. ## Testing - Tested using the sample project and deep linking via `adb shell am start -a android.intent.action.VIEW -d https://www.Iana.org/domains/second` - Added new unit tests to the project for the different case insensitive and sensitive sections Test: /gradlew test connectedCheck ## Issues Fixed https://issuetracker.google.com/issues/153829033 Fixes: b/153829033 This is an imported pull request from androidx#144. Resolves JetBrains#144 Github-Pr-Head-Sha: 868bcf3 GitOrigin-RevId: 0c50731 Change-Id: Ic03b432ffc9f8a71fccad3f01c13232561366d46
1 parent f411539 commit b259aac

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

‎navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,4 +1049,66 @@ class NavDeepLinkTest {
10491049
.that(matchArgs?.getInt("id"))
10501050
.isEqualTo(id)
10511051
}
1052+
1053+
@Test
1054+
fun deepLinkCaseInsensitiveDomainWithPath() {
1055+
val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users/{id}/posts"
1056+
val deepLink = NavDeepLink(deepLinkArgument)
1057+
1058+
val id = 2
1059+
val matchArgs = deepLink.getMatchingArguments(
1060+
Uri.parse("${DEEP_LINK_EXACT_HTTPS.toUpperCase()}/users/$id/posts"),
1061+
mapOf("id" to intArgument())
1062+
)
1063+
assertWithMessage("Args should not be null")
1064+
.that(matchArgs)
1065+
.isNotNull()
1066+
assertWithMessage("Args should contain the id")
1067+
.that(matchArgs?.getInt("id"))
1068+
.isEqualTo(id)
1069+
}
1070+
1071+
@Test
1072+
fun deepLinkCaseInsensitivePath() {
1073+
val deepLinkArgument = "$DEEP_LINK_EXACT_HTTPS/users/{id}/posts"
1074+
val deepLink = NavDeepLink(deepLinkArgument)
1075+
1076+
val id = 2
1077+
val matchArgs = deepLink.getMatchingArguments(
1078+
Uri.parse(
1079+
deepLinkArgument
1080+
.replace("{id}", id.toString())
1081+
.replace("users", "Users")
1082+
),
1083+
mapOf("id" to intArgument())
1084+
)
1085+
assertWithMessage("Args should not be null")
1086+
.that(matchArgs)
1087+
.isNotNull()
1088+
assertWithMessage("Args should contain the id")
1089+
.that(matchArgs?.getInt("id"))
1090+
.isEqualTo(id)
1091+
}
1092+
1093+
@Test
1094+
fun deepLinkCaseSensitiveQueryParams() {
1095+
val deepLinkString = "$DEEP_LINK_EXACT_HTTP/?myParam={param}"
1096+
val deepLink = NavDeepLink(deepLinkString)
1097+
1098+
val param = 2
1099+
val deepLinkUpper = deepLinkString
1100+
.replace("myParam", "MYPARAM")
1101+
.replace("{param}", param.toString())
1102+
val matchArgs = deepLink.getMatchingArguments(
1103+
Uri.parse(deepLinkUpper),
1104+
mapOf("param" to intArgument())
1105+
)
1106+
1107+
assertWithMessage("Args should be not be null")
1108+
.that(matchArgs)
1109+
.isNotNull()
1110+
assertWithMessage("Args bundle should be empty")
1111+
.that(matchArgs?.isEmpty)
1112+
.isTrue()
1113+
}
10521114
}

‎navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public class NavDeepLink internal constructor(
422422
// specifically escape any .* instances to ensure
423423
// they are still treated as wildcards in our final regex
424424
val finalRegex = uriRegex.toString().replace(".*", "\\E.*\\Q")
425-
pattern = Pattern.compile(finalRegex)
425+
pattern = Pattern.compile(finalRegex, Pattern.CASE_INSENSITIVE)
426426
}
427427
if (mimeType != null) {
428428
val mimeTypePattern = Pattern.compile("^[\\s\\S]+/[\\s\\S]+$")

0 commit comments

Comments
 (0)