From 2a2c61973eb14c181f18e1997d52d391e374134f Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 24 Mar 2026 13:30:36 -0400 Subject: [PATCH] Avoids crashing the app in weird urls. --- .../amethyst/commons/richtext/UrlParser.kt | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParser.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParser.kt index 9c6c6007b..6356b2e37 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParser.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/UrlParser.kt @@ -22,9 +22,11 @@ package com.vitorpamplona.amethyst.commons.richtext import androidx.compose.runtime.Stable import com.vitorpamplona.quartz.utils.DualCase +import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.startsWithAny import com.vitorpamplona.quartz.utils.urldetector.Url import com.vitorpamplona.quartz.utils.urldetector.detection.UrlDetector +import kotlinx.coroutines.CancellationException @Stable class Urls( @@ -77,30 +79,35 @@ class UrlParser { val blossom = mutableSetOf() urls.forEach { url -> - if (url.isValidTopLevelDomain()) { - if (url.wroteWithSchema()) { - if (url.originalUrl.startsWithAny(httpScheme)) { - // quick exit - completeUrls.add(url.originalUrl) - } else if (url.originalUrl.startsWithAny(nostrScheme)) { - bech32.add(url.originalUrl) - } else if (url.originalUrl.startsWithAny(websocketScheme)) { - relays.add(url.originalUrl) - } else if (url.originalUrl.startsWithAny(blossomScheme)) { - blossom.add(url.originalUrl) - } else { - completeUrls.add(url.originalUrl) - } - } else { - // emails are understood as urls from the detector. - if (url.isEmail()) { - Patterns.EMAIL_ADDRESS.findAll(url.originalUrl).forEach { - emails.add(it.value) + try { + if (url.isValidTopLevelDomain()) { + if (url.wroteWithSchema()) { + if (url.originalUrl.startsWithAny(httpScheme)) { + // quick exit + completeUrls.add(url.originalUrl) + } else if (url.originalUrl.startsWithAny(nostrScheme)) { + bech32.add(url.originalUrl) + } else if (url.originalUrl.startsWithAny(websocketScheme)) { + relays.add(url.originalUrl) + } else if (url.originalUrl.startsWithAny(blossomScheme)) { + blossom.add(url.originalUrl) + } else { + completeUrls.add(url.originalUrl) } } else { - urlsWithoutScheme.add(url.originalUrl) + // emails are understood as urls from the detector. + if (url.isEmail()) { + Patterns.EMAIL_ADDRESS.findAll(url.originalUrl).forEach { + emails.add(it.value) + } + } else { + urlsWithoutScheme.add(url.originalUrl) + } } } + } catch (e: Exception) { + if (e is CancellationException) throw e + Log.e("UrlParser", "Trying to parse url `${url.originalUrl}` from `$content`", e) } }