Detailed changes
@@ -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);
@@ -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() {
@@ -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()) {
@@ -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 {
@@ -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;
+ }
}