From a4aff0f76ddd147495c09f7d1dc9c2837ba7a3b0 Mon Sep 17 00:00:00 2001 From: Davis Wolfermann Date: Tue, 29 Sep 2026 16:44:21 +0200 Subject: [PATCH] fix(util): return null instead of throwing for domains IDN rejects Fixes #107 --- .../data/resolver/OkHttpRegistrableDomainResolver.kt | 10 +++++++++- .../resolver/OkHttpRegistrableDomainResolverTest.kt | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core/util/src/main/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolver.kt b/core/util/src/main/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolver.kt index e6f015998..af8e9fc3a 100644 --- a/core/util/src/main/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolver.kt +++ b/core/util/src/main/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolver.kt @@ -17,9 +17,17 @@ internal class OkHttpRegistrableDomainResolver : RegistrableDomainResolver { val candidate = if ("://" !in hostOrNull) "https://$hostOrNull" else hostOrNull val url = candidate.toHttpUrlOrNull() - ?: "https://${IDN.toASCII(domain)}".toHttpUrlOrNull() + ?: domain.idnToAsciiOrNull()?.let { "https://$it".toHttpUrlOrNull() } ?: return null return url.topPrivateDomain() } + + // IDN throws, rather than returning, on anything DNS cannot hold: a label over 63 characters or, + // on Android, a name too long overall. Free text in a website field reaches here as is. + private fun String.idnToAsciiOrNull(): String? = try { + IDN.toASCII(this) + } catch (_: IllegalArgumentException) { + null + } } \ No newline at end of file diff --git a/core/util/src/test/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolverTest.kt b/core/util/src/test/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolverTest.kt index 8fcb4e9c0..2ef77dcb8 100644 --- a/core/util/src/test/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolverTest.kt +++ b/core/util/src/test/kotlin/de/davis/keygo/core/util/data/resolver/OkHttpRegistrableDomainResolverTest.kt @@ -135,6 +135,15 @@ class OkHttpRegistrableDomainResolverTest { assertEquals(expected = expected, actual = result) } + @Test + fun `resolves label longer than DNS allows to null`() { + val domain = "a".repeat(64) + ".com" + val expected = null + val result = resolver.resolve(domain) + + assertEquals(expected = expected, actual = result) + } + @Test fun `resolves IPv4 to null`() { val domain = "127.0.0.1"