diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index ca255cfc..936e046c 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -59,7 +59,7 @@ public class PgpEngine { message.setEncryption(Message.ENCRYPTION_DECRYPTED); final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() - && message.bodyContainsDownloadable() + && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index d80400d8..bf68d018 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -375,8 +375,8 @@ public class Message extends AbstractEntity { (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !GeoHelper.isGeoUri(message.getBody()) && !GeoHelper.isGeoUri(this.body) && - !message.bodyContainsDownloadable() && - !this.bodyContainsDownloadable() && + message.treatAsDownloadable() == Decision.NO && + this.treatAsDownloadable() == Decision.NO && !message.getBody().startsWith(ME_COMMAND) && !this.getBody().startsWith(ME_COMMAND) && !this.bodyIsHeart() && @@ -434,48 +434,50 @@ public class Message extends AbstractEntity { return (status > STATUS_RECEIVED || (contact != null && contact.trusted())); } - public boolean bodyContainsDownloadable() { - /** - * there are a few cases where spaces result in an unwanted behavior, e.g. - * "http://example.com/image.jpg text that will not be shown /abc.png" - * or more than one image link in one message. - */ + public enum Decision { + YES, + NO, + ASK + } + + public Decision treatAsDownloadable() { if (body.trim().contains(" ")) { - return false; + return Decision.NO; } try { URL url = new URL(body); - if (!url.getProtocol().equalsIgnoreCase("http") - && !url.getProtocol().equalsIgnoreCase("https")) { - return false; + if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { + return Decision.NO; + } + String path = url.getPath(); + if (path == null || path.isEmpty()) { + return Decision.NO; } - String sUrlPath = url.getPath(); - if (sUrlPath == null || sUrlPath.isEmpty()) { - return false; - } - - int iSlashIndex = sUrlPath.lastIndexOf('/') + 1; - - String sLastUrlPath = sUrlPath.substring(iSlashIndex).toLowerCase(); - - String[] extensionParts = sLastUrlPath.split("\\."); - if (extensionParts.length == 2 - && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 1])) { - return true; - } else if (extensionParts.length == 3 - && Arrays + String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); + String[] extensionParts = filename.split("\\."); + String extension; + String ref = url.getRef(); + if (extensionParts.length == 2) { + extension = extensionParts[extensionParts.length - 1]; + } else if (extensionParts.length == 3 && Arrays .asList(Downloadable.VALID_CRYPTO_EXTENSIONS) - .contains(extensionParts[extensionParts.length - 1]) - && Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains( - extensionParts[extensionParts.length - 2])) { - return true; + .contains(extensionParts[extensionParts.length - 1])) { + extension = extensionParts[extensionParts.length -2]; } else { - return false; + return Decision.NO; } + + if (Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(extension)) { + return Decision.YES; + } else if (ref != null && ref.matches("([A-Fa-f0-9]{2}){48}")) { + return Decision.ASK; + } else { + return Decision.NO; + } + } catch (MalformedURLException e) { - return false; + return Decision.NO; } } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a40b170..6d2aebf2 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -360,7 +360,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + if (message.trusted() && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index e1de0b23..6d37bbd5 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -497,7 +497,7 @@ public class FileBackend { message.setBody(url.toString()+"|"+Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight); } } else { - message.setBody(Long.toString(file.getSize())); + message.setBody(url.toString()+"|"+Long.toString(file.getSize())); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index f7022ee5..b7400a94 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -457,7 +457,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null - || !m.bodyContainsDownloadable()) { + || m.treatAsDownloadable() == Message.Decision.NO) { downloadImage.setVisible(false); } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder))