From 3f7dd2118654516aea26cd87e095a4ad87d2a606 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 17 Aug 2020 10:27:26 -0400 Subject: [PATCH] Do not attempt to create link previews for .onion links. --- .../linkpreview/LinkPreviewUtil.java | 28 ++++++++++++++++--- .../LinkPreviewUtilTest_isLegal.java | 1 + 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtil.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtil.java index b1fb95ccb..be20b0c7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtil.java @@ -11,6 +11,7 @@ import android.text.style.URLSpan; import android.text.util.Linkify; import com.annimon.stream.Stream; +import com.google.android.collect.Sets; import org.thoughtcrime.securesms.stickers.StickerUrl; import org.thoughtcrime.securesms.util.Util; @@ -21,6 +22,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,6 +39,8 @@ public final class LinkPreviewUtil { private static final Pattern FAVICON_PATTERN = Pattern.compile("<\\s*link[^>]*rel\\s*=\\s*\".*icon.*\"[^>]*>"); private static final Pattern FAVICON_HREF_PATTERN = Pattern.compile("href\\s*=\\s*\"([^\"]*)\""); + private static final Set INVALID_TOP_LEVEL_DOMAINS = Sets.newHashSet("onion"); + /** * @return All whitelisted URLs in the source text. */ @@ -72,11 +76,16 @@ public final class LinkPreviewUtil { Matcher matcher = DOMAIN_PATTERN.matcher(url); if (matcher.matches()) { - String domain = matcher.group(2); - String cleanedDomain = domain.replaceAll("\\.", ""); + String domain = matcher.group(2); + String cleanedDomain = domain.replaceAll("\\.", ""); + String topLevelDomain = parseTopLevelDomain(domain); - return ALL_ASCII_PATTERN.matcher(cleanedDomain).matches() || - ALL_NON_ASCII_PATTERN.matcher(cleanedDomain).matches(); + boolean validCharacters = ALL_ASCII_PATTERN.matcher(cleanedDomain).matches() || + ALL_NON_ASCII_PATTERN.matcher(cleanedDomain).matches(); + + boolean validTopLevelDomain = !INVALID_TOP_LEVEL_DOMAINS.contains(topLevelDomain); + + return validCharacters && validTopLevelDomain; } else { return false; } @@ -127,6 +136,17 @@ public final class LinkPreviewUtil { return new OpenGraph(openGraphTags, htmlTitle, faviconUrl); } + private static @Nullable String parseTopLevelDomain(@NonNull String domain) { + int periodIndex = domain.lastIndexOf("."); + + if (periodIndex >= 0 && periodIndex < domain.length() - 1) { + return domain.substring(periodIndex + 1); + } else { + return null; + } + } + + public static final class OpenGraph { private final Map values; diff --git a/app/src/test/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtilTest_isLegal.java b/app/src/test/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtilTest_isLegal.java index 905337f5f..0cf3f49c7 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtilTest_isLegal.java +++ b/app/src/test/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewUtilTest_isLegal.java @@ -28,6 +28,7 @@ public class LinkPreviewUtilTest_isLegal { { "кц.com", false }, { "http://asĸ.com", false }, { "http://foo.кц.рф", false }, + { "https://abcdefg.onion", false }, { "", false } }); }