Change summary
src/main/java/de/gultsch/common/Linkify.java | 14 ++++++
src/test/java/de/gultsch/common/LinkifyTest.java | 37 ++++++++++++++++++
2 files changed, 51 insertions(+)
Detailed changes
@@ -45,6 +45,8 @@ import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.utils.StylingHelper;
import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xmpp.Jid;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -59,6 +61,9 @@ public class Linkify {
if (scheme == null) {
return false;
}
+ if (!isValidUri(match)) {
+ return false;
+ }
return switch (scheme) {
case "tel" -> Patterns.URI_TEL.matcher(match).matches();
case "http", "https" -> Patterns.URI_HTTP.matcher(match).matches();
@@ -77,6 +82,15 @@ public class Linkify {
};
}
+ private static boolean isValidUri(final String match) {
+ try {
+ new URI(match);
+ return true;
+ } catch (final URISyntaxException e) {
+ return false;
+ }
+ }
+
public static void addLinks(final Spannable body) {
android.text.util.Linkify.addLinks(body, Patterns.URI_GENERIC, null, MATCH_FILTER, null);
}
@@ -0,0 +1,37 @@
+package de.gultsch.common;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LinkifyTest {
+
+ @Test
+ public void malformedEscapeIsRejected() {
+ final var links = Linkify.getLinks("https://example.com/?x=%");
+
+ Assert.assertTrue(links.isEmpty());
+ }
+
+ @Test
+ public void validEscapesStillProduceLinks() {
+ final var links = Linkify.getLinks("https://example.com/?x=%20");
+
+ Assert.assertEquals(1, links.size());
+ Assert.assertEquals("https://example.com/?x=%20", links.get(0).getRaw());
+ }
+
+ @Test
+ public void ipv6HostsStillProduceLinks() {
+ final var links = Linkify.getLinks("http://[::1]/foo");
+
+ Assert.assertEquals(1, links.size());
+ Assert.assertEquals("http://[::1]/foo", links.get(0).getRaw());
+ }
+
+ @Test
+ public void bracketsInPathAreRejected() {
+ final var links = Linkify.getLinks("http://example.com/foo[bar]");
+
+ Assert.assertTrue(links.isEmpty());
+ }
+}