diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java index 4fa803591..10deacfe4 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java @@ -2,7 +2,9 @@ package eu.siacs.conversations.crypto; import android.app.PendingIntent; import android.content.Intent; +import android.util.Log; +import org.openintents.openpgp.OpenPgpMetadata; import org.openintents.openpgp.util.OpenPgpApi; import java.io.ByteArrayInputStream; @@ -17,11 +19,13 @@ import java.util.ArrayDeque; import java.util.HashSet; import java.util.List; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.MimeUtils; public class PgpDecryptionService { @@ -176,13 +180,31 @@ public class PgpDecryptionService { try { final DownloadableFile inputFile = mXmppConnectionService.getFileBackend().getFile(message, false); final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true); - outputFile.getParentFile().mkdirs(); + if (outputFile.getParentFile().mkdirs()) { + Log.d(Config.LOGTAG,"created parent directories for "+outputFile.getAbsolutePath()); + } outputFile.createNewFile(); InputStream is = new FileInputStream(inputFile); OutputStream os = new FileOutputStream(outputFile); Intent result = getOpenPgpApi().executeApi(params, is, os); switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: + OpenPgpMetadata openPgpMetadata = result.getParcelableExtra(OpenPgpApi.RESULT_METADATA); + String originalFilename = openPgpMetadata.getFilename(); + String originalExtension = originalFilename == null ? null : MimeUtils.extractRelevantExtension(originalFilename); + if (originalExtension != null && MimeUtils.extractRelevantExtension(outputFile.getName()) == null) { + Log.d(Config.LOGTAG,"detected original filename during pgp decryption"); + String mime = MimeUtils.guessMimeTypeFromExtension(originalExtension); + String path = outputFile.getName()+"."+originalExtension; + DownloadableFile fixedFile = mXmppConnectionService.getFileBackend().getFileForPath(path,mime); + if (fixedFile.getParentFile().mkdirs()) { + Log.d(Config.LOGTAG,"created parent directories for "+fixedFile.getAbsolutePath()); + } + if (outputFile.renameTo(fixedFile)) { + Log.d(Config.LOGTAG, "renamed " + outputFile.getAbsolutePath() + " to " + fixedFile.getAbsolutePath()); + message.setRelativeFilePath(path); + } + } URL url = message.getFileParams().url; mXmppConnectionService.getFileBackend().updateFileParams(message, url); message.setEncryption(Message.ENCRYPTION_DECRYPTED); diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 22c737e1c..5187658b5 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -680,46 +680,19 @@ public class Message extends AbstractEntity { this.oob = isOob; } - private static String extractRelevantExtension(URL url) { - String path = url.getPath(); - return extractRelevantExtension(path); - } - - private static String extractRelevantExtension(String path) { - if (path == null || path.isEmpty()) { - return null; - } - - String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); - int dotPosition = filename.lastIndexOf("."); - - if (dotPosition != -1) { - String extension = filename.substring(dotPosition + 1); - // we want the real file extension, not the crypto one - if (Transferable.VALID_CRYPTO_EXTENSIONS.contains(extension)) { - return extractRelevantExtension(filename.substring(0,dotPosition)); - } else { - return extension; - } - } - return null; - } - public String getMimeType() { + String extension; if (relativeFilePath != null) { - int start = relativeFilePath.lastIndexOf('.') + 1; - if (start < relativeFilePath.length()) { - return MimeUtils.guessMimeTypeFromExtension(relativeFilePath.substring(start)); - } else { - return null; - } + extension = MimeUtils.extractRelevantExtension(relativeFilePath); } else { try { - return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(body.trim()))); + final URL url = new URL(body.split("\n")[0]); + extension = MimeUtils.extractRelevantExtension(url); } catch (MalformedURLException e) { return null; } } + return MimeUtils.guessMimeTypeFromExtension(extension); } public synchronized boolean treatAsDownloadable() { diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index bd8921ce4..fa3df7494 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -89,7 +89,7 @@ public class HttpDownloadConnection implements Transferable { } else { extension = lastPart; } - message.setRelativeFilePath(message.getUuid() + "." + extension); + message.setRelativeFilePath(message.getUuid() + (extension != null ? ("." + extension) : "")); this.file = mXmppConnectionService.getFileBackend().getFile(message, false); final String reference = mUrl.getRef(); if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 48c52b89d..1ff8541b4 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -110,19 +110,11 @@ public class FileBackend { return getFile(message, true); } - public DownloadableFile getFile(Message message, boolean decrypted) { - final boolean encrypted = !decrypted - && (message.getEncryption() == Message.ENCRYPTION_PGP - || message.getEncryption() == Message.ENCRYPTION_DECRYPTED); + public DownloadableFile getFileForPath(String path, String mime) { final DownloadableFile file; - String path = message.getRelativeFilePath(); - if (path == null) { - path = message.getUuid(); - } if (path.startsWith("/")) { file = new DownloadableFile(path); } else { - String mime = message.getMimeType(); if (mime != null && mime.startsWith("image/")) { file = new DownloadableFile(getConversationsDirectory("Images") + path); } else if (mime != null && mime.startsWith("video/")) { @@ -131,6 +123,18 @@ public class FileBackend { file = new DownloadableFile(getConversationsDirectory("Files") + path); } } + return file; + } + + public DownloadableFile getFile(Message message, boolean decrypted) { + final boolean encrypted = !decrypted + && (message.getEncryption() == Message.ENCRYPTION_PGP + || message.getEncryption() == Message.ENCRYPTION_DECRYPTED); + String path = message.getRelativeFilePath(); + if (path == null) { + path = message.getUuid(); + } + final DownloadableFile file = getFileForPath(path, message.getMimeType()); if (encrypted) { return new DownloadableFile(getConversationsDirectory("Files") + file.getName() + ".pgp"); } else { diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java index 64776f59c..78b5dd6a9 100644 --- a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java @@ -21,9 +21,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Properties; + +import eu.siacs.conversations.entities.Transferable; + /** * Utilities for dealing with MIME types. * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap. @@ -510,4 +514,33 @@ public final class MimeUtils { } return mimeType; } + + public static String extractRelevantExtension(URL url) { + String path = url.getPath(); + return extractRelevantExtension(path, true); + } + + public static String extractRelevantExtension(final String path) { + return extractRelevantExtension(path, false); + } + + public static String extractRelevantExtension(final String path, final boolean ignoreCryptoExtension) { + if (path == null || path.isEmpty()) { + return null; + } + + String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); + int dotPosition = filename.lastIndexOf("."); + + if (dotPosition != -1) { + String extension = filename.substring(dotPosition + 1); + // we want the real file extension, not the crypto one + if (ignoreCryptoExtension && Transferable.VALID_CRYPTO_EXTENSIONS.contains(extension)) { + return extractRelevantExtension(filename.substring(0,dotPosition)); + } else { + return extension; + } + } + return null; + } }