Skip to content

Commit 3ebf199

Browse files
rossbacherAndreas Rossbacher
andauthored
Fix issues with long placeholders in hosts. (#335)
* Hosts can be very long if they have placeholders (in templates) and this might not process correctlty. So we replace the placeholders with short ones and rereplace them after processing. This is safe as this is only done for templates and placeholder format is well understood. Added tests * Fix formatting * Added comment. * Updated comment. Co-authored-by: Andreas Rossbacher <andreas.rossbacher@airbnb.com>
1 parent 35d3427 commit 3ebf199

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

deeplinkdispatch-base/src/main/java/com/airbnb/deeplinkdispatch/DeepLinkUri.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@
3232
import java.util.ArrayList;
3333
import java.util.Arrays;
3434
import java.util.Collections;
35+
import java.util.HashMap;
3536
import java.util.HashSet;
3637
import java.util.LinkedHashSet;
3738
import java.util.List;
3839
import java.util.Locale;
40+
import java.util.Map;
3941
import java.util.Set;
4042
import java.util.regex.Matcher;
4143
import java.util.regex.Pattern;
@@ -321,7 +323,7 @@ Set<String> getSchemeHostPathPlaceholders() {
321323
}
322324

323325
@NotNull
324-
private Set<String> getPlaceHolders(String input) {
326+
private static Set<String> getPlaceHolders(String input) {
325327
final Matcher matcher = PLACEHOLDER_REGEX.matcher(input);
326328
Set<String> placeholders = new HashSet<>(matcher.groupCount());
327329
while (matcher.find()) {
@@ -1215,7 +1217,22 @@ private static boolean decodeIpv4Suffix(
12151217
*/
12161218
private static String domainToAscii(String input) {
12171219
try {
1218-
String result = IDN.toASCII(input).toLowerCase(Locale.US);
1220+
// When this is a template URI it might get to long (> 256 chars) with all the placeholder
1221+
// definitions to pass verification.
1222+
// This will replace the placeholders with other shorter placeholders for URI validation.
1223+
Set<String> placeholders = getPlaceHolders(input);
1224+
String mappedInput = input;
1225+
Map<String, String> placeholderMap = new HashMap(placeholders.size());
1226+
int i = 0;
1227+
for (String placeholder : placeholders) {
1228+
String replacedValue = "" + (i++);
1229+
mappedInput = mappedInput.replace(placeholder, replacedValue);
1230+
placeholderMap.put(placeholder, replacedValue);
1231+
}
1232+
String result = IDN.toASCII(mappedInput).toLowerCase(Locale.US);
1233+
for (Map.Entry<String, String> entry : placeholderMap.entrySet()) {
1234+
result = result.replace(entry.getValue(), entry.getKey());
1235+
}
12191236
if (result.isEmpty()) return null;
12201237

12211238
if (result == null) return null;

deeplinkdispatch-base/src/test/java/com/airbnb/deeplinkdispatch/DeeplinkUriTest.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ class DeeplinkUriTest {
3131
assertEquals(listOf("path1", "path2"), deeplinkUriTemplate.pathSegments())
3232
}
3333

34+
@Test
35+
fun testParseDeepLinkUriTemplateWithVeryLongHost() {
36+
val host =
37+
"www.example.{url_domain_suffix(just|a|lot|of|values|in|here|that|make|the|url|very|long|longer|than|264|characters|to|be|creating|some|problems|with|ID|decode)}"
38+
val deeplinkUriTemplate = DeepLinkUri.parseTemplate("http{scheme_suffix}://$host/path1/path2")
39+
assertNotNull(deeplinkUriTemplate)
40+
assertEquals("http{scheme_suffix}", deeplinkUriTemplate.scheme())
41+
assertEquals(host, deeplinkUriTemplate.host())
42+
assertEquals(listOf("path1", "path2"), deeplinkUriTemplate.pathSegments())
43+
}
44+
3445
@Test
3546
fun testParseDeepLinkUriTemplateWithOnlyPlaceholderAsHostAndScheme() {
3647
val deeplinkUriTemplate = DeepLinkUri.parseTemplate("{scheme}://{host}/path1/path2")

0 commit comments

Comments
 (0)