From 980c2256f17309d778431ce9dd2687ebc62fe800 Mon Sep 17 00:00:00 2001 From: Andy Stadler Date: Mon, 24 Jan 2011 18:06:53 -0800 Subject: [PATCH] Catch base64 errors and handle in-place Bug: 3362752 Change-Id: I63adb8663c90a7710176cc1c481bbfa5b4b859c4 --- src/com/android/email/Email.java | 13 ++++++++++ .../email/mail/internet/MimeUtility.java | 11 ++++++-- .../android/email/mail/store/ImapStore.java | 25 ++++++++++++------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/com/android/email/Email.java b/src/com/android/email/Email.java index 30f1c24c5..5815bfce6 100644 --- a/src/com/android/email/Email.java +++ b/src/com/android/email/Email.java @@ -184,6 +184,8 @@ public class Email extends Application { private static File sTempDirectory; + private static String sMessageDecodeErrorString; + private static Thread sUiThread; public static void setTempDirectory(Context context) { @@ -306,6 +308,9 @@ public class Email extends Application { // Enable logging in the EAS service, so it starts up as early as possible. updateLoggingFlags(this); + + // Get a helper string used deep inside message decoders (which don't have context) + sMessageDecodeErrorString = getString(R.string.message_decode_error); } /** @@ -352,4 +357,12 @@ public class Email extends Application { Log.w(Email.LOG_TAG, "Method called on the UI thread", new Exception("STACK TRACE")); } } + + /** + * Retrieve a simple string that can be used when message decoders encounter bad data. + * This is provided here because the protocol decoders typically don't have mContext. + */ + public static String getMessageDecodeErrorString() { + return sMessageDecodeErrorString != null ? sMessageDecodeErrorString : ""; + } } diff --git a/src/com/android/email/mail/internet/MimeUtility.java b/src/com/android/email/mail/internet/MimeUtility.java index e3145f950..65bb3a798 100644 --- a/src/com/android/email/mail/internet/MimeUtility.java +++ b/src/com/android/email/mail/internet/MimeUtility.java @@ -31,6 +31,7 @@ import org.apache.james.mime4j.decoder.QuotedPrintableInputStream; import org.apache.james.mime4j.util.CharsetUtil; import android.util.Base64; +import android.util.Base64DataException; import android.util.Base64InputStream; import android.util.Log; @@ -379,8 +380,14 @@ public class MimeUtility { in = getInputStreamForContentTransferEncoding(in, contentTransferEncoding); BinaryTempFileBody tempBody = new BinaryTempFileBody(); OutputStream out = tempBody.getOutputStream(); - IOUtils.copy(in, out); - out.close(); + try { + IOUtils.copy(in, out); + } catch (Base64DataException bde) { + String warning = "\n\n" + Email.getMessageDecodeErrorString(); + out.write(warning.getBytes()); + } finally { + out.close(); + } return tempBody; } diff --git a/src/com/android/email/mail/store/ImapStore.java b/src/com/android/email/mail/store/ImapStore.java index f14116f83..143c416f8 100644 --- a/src/com/android/email/mail/store/ImapStore.java +++ b/src/com/android/email/mail/store/ImapStore.java @@ -56,6 +56,7 @@ import android.os.Bundle; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Base64; +import android.util.Base64DataException; import android.util.Config; import android.util.Log; @@ -1039,17 +1040,23 @@ public class ImapStore extends Store { in = MimeUtility.getInputStreamForContentTransferEncoding(in, contentTransferEncoding); BinaryTempFileBody tempBody = new BinaryTempFileBody(); OutputStream out = tempBody.getOutputStream(); - byte[] buffer = new byte[COPY_BUFFER_SIZE]; - int n = 0; - int count = 0; - while (-1 != (n = in.read(buffer))) { - out.write(buffer, 0, n); - count += n; - if (listener != null) { - listener.loadAttachmentProgress(count * 100 / size); + try { + byte[] buffer = new byte[COPY_BUFFER_SIZE]; + int n = 0; + int count = 0; + while (-1 != (n = in.read(buffer))) { + out.write(buffer, 0, n); + count += n; + if (listener != null) { + listener.loadAttachmentProgress(count * 100 / size); + } } + } catch (Base64DataException bde) { + String warning = "\n\n" + Email.getMessageDecodeErrorString(); + out.write(warning.getBytes()); + } finally { + out.close(); } - out.close(); return tempBody; }