Fixed linkifying URLs with commas.

This commit is contained in:
Greyson Parrelli 2026-06-02 11:18:01 -04:00 committed by Alex Hart
parent 47a69d667c
commit 4e5ddad78f
2 changed files with 5 additions and 3 deletions

View File

@ -28,11 +28,11 @@ object Linkifier {
private val CLOSING_BRACKETS = mapOf(')' to '(', ']' to '[', '}' to '{')
/**
* Characters we treat as definitely-not-part-of-a-URL when extending past the host. Excluding
* commas/semicolons here lets `https://a.com,https://b.com` resolve to two URLs rather than one.
* Characters we treat as definitely-not-part-of-a-URL when extending past the host. Commas are
* allowed inside a URL, but not when they are acting as a separator before another obvious URL.
*/
private const val URL_CHAR =
"[^\\s\\u0085\\u00A0\\u1680\\u2000-\\u200D\\u2028\\u2029\\u202A-\\u202F\\u205F\\u2066-\\u2069\\u3000\\uFEFF<>\"'`,;|\\\\]"
"(?:[^\\s\\u0085\\u00A0\\u1680\\u2000-\\u200D\\u2028\\u2029\\u202A-\\u202F\\u205F\\u2066-\\u2069\\u3000\\uFEFF<>\"'`,;|\\\\]|,(?!https?://|www\\.))"
/**
* A single domain label: letter/digit, optional letter/digit/hyphen body. Used for intermediate

View File

@ -103,6 +103,8 @@ class LinkifierTest(private val case: Case) {
Case("multiple trailing punctuation chars are all trimmed", "Wow https://signal.org!!! amazing", listOf(web("https://signal.org"))),
Case("trailing slash is preserved", "https://signal.org/ end", listOf(web("https://signal.org/"))),
Case("trailing underscore is preserved", "https://example.com/path_ tail", listOf(web("https://example.com/path_"))),
Case("comma in url path is preserved", "Go to https://example.com/a,b/c", listOf(web("https://example.com/a,b/c"))),
Case("comma in url query is preserved", "Go to https://example.com/search?q=a,b", listOf(web("https://example.com/search?q=a,b"))),
// ----- bracket / paren handling -----
Case("trailing closing paren without opener is trimmed", "(see https://signal.org)", listOf(web("https://signal.org"))),