From 1ac876fa1a5522964e1782d929761de861925100 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 11 Mar 2022 14:20:54 +0100 Subject: [PATCH] Limit zip file size --- .../email/FragmentOptionsDisplay.java | 4 +- .../java/eu/faircode/email/MessageHelper.java | 89 ++++++++++--------- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java index b7b16fd45e..6c4965623f 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java @@ -1177,7 +1177,9 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer } }); - tvUnzipHint.setText(getString(R.string.title_advanced_unzip_hint, MessageHelper.MAX_UNZIP)); + tvUnzipHint.setText(getString(R.string.title_advanced_unzip_hint, + Integer.toString(MessageHelper.MAX_UNZIP_COUNT), + Helper.humanReadableByteCount(MessageHelper.MAX_UNZIP_SIZE))); swAttachmentsAlt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 0f5a1a1896..3ca23e1f12 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -50,7 +50,6 @@ import com.sun.mail.util.FolderClosedIOException; import com.sun.mail.util.MessageRemovedIOException; import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; @@ -99,8 +98,6 @@ import java.util.TimeZone; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; import javax.activation.DataHandler; import javax.activation.FileDataSource; @@ -149,7 +146,8 @@ public class MessageHelper { static final String HEADER_CORRELATION_ID = "X-Correlation-ID"; static final int MAX_SUBJECT_AGE = 48; // hours static final int DEFAULT_THREAD_RANGE = 7; // 2^7 = 128 days - static final int MAX_UNZIP = 10; + static final int MAX_UNZIP_COUNT = 20; + static final long MAX_UNZIP_SIZE = 1000 * 1000 * 1000L; static final List RECEIVED_WORDS = Collections.unmodifiableList(Arrays.asList( "from", "by", "via", "with", "id", "for" @@ -3395,46 +3393,48 @@ public class MessageHelper { Log.i("Gzipped attachment seq=" + local.sequence + " " + name + ":" + total); - if (name == null && - local.name != null && local.name.endsWith(".gz")) - name = local.name.substring(0, local.name.length() - 3); - - EntityAttachment attachment = new EntityAttachment(); - attachment.message = local.message; - attachment.sequence = local.sequence; - attachment.subsequence = 1; - attachment.name = name; - attachment.type = Helper.guessMimeType(name); - if (total >= 0) - attachment.size = total; - attachment.id = db.attachment().insertAttachment(attachment); - - File efile = attachment.getFile(context); - Log.i("Gunzipping to " + efile); - - int last = 0; - long size = 0; - try (OutputStream os = new FileOutputStream(efile)) { - byte[] buffer = new byte[Helper.BUFFER_SIZE]; - for (int len = gzip.read(buffer); len != -1; len = gzip.read(buffer)) { - size += len; - os.write(buffer, 0, len); - - if (total > 0) { - int progress = (int) (size * 100 / total); - if (progress / 20 > last / 20) { - last = progress; - db.attachment().setProgress(attachment.id, progress); + if (total <= MAX_UNZIP_SIZE) { + if (name == null && + local.name != null && local.name.endsWith(".gz")) + name = local.name.substring(0, local.name.length() - 3); + + EntityAttachment attachment = new EntityAttachment(); + attachment.message = local.message; + attachment.sequence = local.sequence; + attachment.subsequence = 1; + attachment.name = name; + attachment.type = Helper.guessMimeType(name); + if (total >= 0) + attachment.size = total; + attachment.id = db.attachment().insertAttachment(attachment); + + File efile = attachment.getFile(context); + Log.i("Gunzipping to " + efile); + + int last = 0; + long size = 0; + try (OutputStream os = new FileOutputStream(efile)) { + byte[] buffer = new byte[Helper.BUFFER_SIZE]; + for (int len = gzip.read(buffer); len != -1; len = gzip.read(buffer)) { + size += len; + os.write(buffer, 0, len); + + if (total > 0) { + int progress = (int) (size * 100 / total); + if (progress / 20 > last / 20) { + last = progress; + db.attachment().setProgress(attachment.id, progress); + } } } + } catch (Throwable ex) { + Log.e(ex); + db.attachment().setError(attachment.id, Log.formatThrowable(ex)); + db.attachment().setAvailable(attachment.id, true); // unrecoverable } - } catch (Throwable ex) { - Log.e(ex); - db.attachment().setError(attachment.id, Log.formatThrowable(ex)); - db.attachment().setAvailable(attachment.id, true); // unrecoverable - } - db.attachment().setDownloaded(attachment.id, efile.length()); + db.attachment().setDownloaded(attachment.id, efile.length()); + } } catch (Throwable ex) { Log.e(ex); db.attachment().setWarning(local.id, Log.formatThrowable(ex)); @@ -3447,12 +3447,15 @@ public class MessageHelper { int count = 0; ArchiveEntry entry; while ((entry = ais.getNextEntry()) != null) - if (ais.canReadEntryData(entry) && !entry.isDirectory()) - if (++count > MAX_UNZIP) + if (ais.canReadEntryData(entry) && !entry.isDirectory()) { + if (entry.getSize() > MAX_UNZIP_SIZE) + count = MAX_UNZIP_COUNT; + if (++count > MAX_UNZIP_COUNT) break; + } Log.i("Zip entries=" + count); - if (count <= MAX_UNZIP) { + if (count <= MAX_UNZIP_COUNT) { fis.getChannel().position(0); ais = new ArchiveStreamFactory().createArchiveInputStream( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9940275bc6..b2a74f940c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -808,7 +808,7 @@ Plain text only messages will be considered as preformatted This applies to reformatted messages only Inline images are images included in the message - The contents of zip files with up to %1$d files will automatically be shown + The contents of zip files with more than %1$s files or with files larger than %2$s will not be shown This will more accurately display messages, but possibly with a delay Language detection support depends on the device manufacturer