diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 9d154cf89e11af3e4c100f9901e11aa428bedb44..2b9bf6f51a04d4dbc14c2bc6f787edc4b1da5c13 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -547,7 +547,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable Pair result = bodyMinusFallbacks("http://jabber.org/protocol/address", Namespace.OOB); StringBuilder body = result.first; - if (!result.second && getOob() != null) { + final String aesgcm = MessageUtils.aesgcmDownloadable(body.toString()); + if (!result.second && aesgcm != null) { + return body.toString().replace(aesgcm, ""); + } else if (!result.second && getOob() != null) { return body.toString().replace(getOob().toString(), ""); } else if (!result.second && isGeoUri()) { return ""; diff --git a/src/main/java/eu/siacs/conversations/utils/MessageUtils.java b/src/main/java/eu/siacs/conversations/utils/MessageUtils.java index 3f0bf6507db2750ec7ccf488d5a49a957fc0ca1e..7039ec336f75c758e5087340fdc6e1e79263a43c 100644 --- a/src/main/java/eu/siacs/conversations/utils/MessageUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/MessageUtils.java @@ -108,6 +108,33 @@ public class MessageUtils { return validAesGcm || validOob; } + public static String aesgcmDownloadable(final String body) { + final String[] lines = body.split("\n"); + if (lines.length == 0) { + return null; + } + for (final String line : lines) { + if (line.contains("\\s+")) { + return null; + } + } + final URI uri; + try { + uri = new URI(lines[0]); + } catch (final URISyntaxException e) { + return null; + } + if (!URL.WELL_KNOWN_SCHEMES.contains(uri.getScheme())) { + return null; + } + final String ref = uri.getFragment(); + final String protocol = uri.getScheme(); + final boolean encrypted = ref != null && AesGcmURL.IV_KEY.matcher(ref).matches(); + final boolean followedByDataUri = lines.length == 2 && lines[1].startsWith("data:"); + final boolean validAesGcm = AesGcmURL.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted && (lines.length == 1 || followedByDataUri); + return validAesGcm ? lines[0] : null; + } + public static String filterLtrRtl(String body) { return LTR_RTL.matcher(body).replaceFirst(EMPTY_STRING); }