am 99710c6c: am ccf9a34b: Add support for disabling email sanitization
* commit '99710c6cef8a0537c85afcd2618d95c7755865e6':
Add support for disabling email sanitization
diff --git a/src/com/android/mail/browse/ConversationPagerAdapter.java b/src/com/android/mail/browse/ConversationPagerAdapter.java
index 70620b4..a6c794b 100644
--- a/src/com/android/mail/browse/ConversationPagerAdapter.java
+++ b/src/com/android/mail/browse/ConversationPagerAdapter.java
@@ -19,7 +19,7 @@
import android.app.Fragment;
import android.app.FragmentManager;
-import android.content.res.Resources;
+import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.os.Bundle;
@@ -27,6 +27,7 @@
import android.support.v4.view.ViewPager;
import android.view.ViewGroup;
+import com.android.mail.preferences.MailPrefs;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
@@ -37,6 +38,7 @@
import com.android.mail.ui.ConversationViewFragment;
import com.android.mail.ui.SecureConversationViewFragment;
import com.android.mail.utils.FragmentStatePagerAdapter2;
+import com.android.mail.utils.HtmlSanitizer;
import com.android.mail.utils.LogUtils;
public class ConversationPagerAdapter extends FragmentStatePagerAdapter2
@@ -67,10 +69,8 @@
* True iff we are in the process of handling a dataset change.
*/
private boolean mInDataSetChange = false;
- /**
- * Need to keep this around to look up pager title strings.
- */
- private Resources mResources;
+
+ private Context mContext;
/**
* This isn't great to create a circular dependency, but our usage of {@link #getPageTitle(int)}
* requires knowing which page is the currently visible to dynamically name offscreen pages
@@ -81,7 +81,16 @@
* minimize dangling references.
*/
private ViewPager mPager;
- private boolean mSanitizedHtml;
+
+ /**
+ * <tt>true</tt> indicates the server has already sanitized all HTML email from this account.
+ */
+ private boolean mServerSanitizedHtml;
+
+ /**
+ * <tt>true</tt> indicates the client is permitted to sanitize all HTML email for this account.
+ */
+ private boolean mClientSanitizedHtml;
private boolean mStopListeningMode = false;
@@ -104,16 +113,18 @@
private static final String BUNDLE_DETACHED_MODE =
ConversationPagerAdapter.class.getName() + "-detachedmode";
- public ConversationPagerAdapter(Resources res, FragmentManager fm, Account account,
+ public ConversationPagerAdapter(Context context, FragmentManager fm, Account account,
Folder folder, Conversation initialConversation) {
super(fm, false /* enableSavedStates */);
- mResources = res;
+ mContext = context;
mCommonFragmentArgs = AbstractConversationViewFragment.makeBasicArgs(account);
mInitialConversation = initialConversation;
mAccount = account;
mFolder = folder;
- mSanitizedHtml = mAccount.supportsCapability
- (UIProvider.AccountCapabilities.SANITIZED_HTML);
+ mServerSanitizedHtml =
+ mAccount.supportsCapability(UIProvider.AccountCapabilities.SERVER_SANITIZED_HTML);
+ mClientSanitizedHtml =
+ mAccount.supportsCapability(UIProvider.AccountCapabilities.CLIENT_SANITIZED_HTML);
}
public boolean matches(Account account, Folder folder) {
@@ -194,11 +205,23 @@
}
private AbstractConversationViewFragment getConversationViewFragment(Conversation c) {
- if (mSanitizedHtml) {
+ // if Html email bodies are already sanitized by the mail server, scripting can be enabled
+ if (mServerSanitizedHtml) {
return ConversationViewFragment.newInstance(mCommonFragmentArgs, c);
- } else {
- return SecureConversationViewFragment.newInstance(mCommonFragmentArgs, c);
}
+
+ // if this client is permitted to sanitize emails for this account, attempt to do so
+ if (mClientSanitizedHtml) {
+ // if the version of the Html Sanitizer meets or exceeds the required version, the
+ // results of the sanitizer can be trusted and scripting can be enabled
+ final MailPrefs mailPrefs = MailPrefs.get(mContext);
+ if (HtmlSanitizer.VERSION >= mailPrefs.getRequiredSanitizerVersionNumber()) {
+ return ConversationViewFragment.newInstance(mCommonFragmentArgs, c);
+ }
+ }
+
+ // otherwise we do not enable scripting
+ return SecureConversationViewFragment.newInstance(mCommonFragmentArgs, c);
}
@Override
diff --git a/src/com/android/mail/browse/ConversationPagerController.java b/src/com/android/mail/browse/ConversationPagerController.java
index 347b4ae..87190f5 100644
--- a/src/com/android/mail/browse/ConversationPagerController.java
+++ b/src/com/android/mail/browse/ConversationPagerController.java
@@ -117,7 +117,7 @@
mPager.setVisibility(View.VISIBLE);
}
- mPagerAdapter = new ConversationPagerAdapter(mPager.getResources(), mFragmentManager,
+ mPagerAdapter = new ConversationPagerAdapter(mPager.getContext(), mFragmentManager,
account, folder, initialConversation);
mPagerAdapter.setSingletonMode(ENABLE_SINGLETON_INITIAL_LOAD);
mPagerAdapter.setActivityController(mActivityController);
diff --git a/src/com/android/mail/preferences/MailPrefs.java b/src/com/android/mail/preferences/MailPrefs.java
index 4d6957d..609877d 100644
--- a/src/com/android/mail/preferences/MailPrefs.java
+++ b/src/com/android/mail/preferences/MailPrefs.java
@@ -117,6 +117,8 @@
public static final String RECENT_ACCOUNTS = "recent-accounts";
+ public static final String REQUIRED_SANITIZER_VERSION_NUMBER = "required-sanitizer-version-number";
+
public static final ImmutableSet<String> BACKUP_KEYS =
new ImmutableSet.Builder<String>()
.add(DEFAULT_REPLY_ALL)
@@ -527,4 +529,22 @@
public void setRecentAccounts(Set<String> recentAccounts) {
getEditor().putStringSet(PreferenceKeys.RECENT_ACCOUNTS, recentAccounts).apply();
}
+
+ /**
+ * Returns the minimum version number of the {@link com.android.mail.utils.HtmlSanitizer} which
+ * is trusted. If the version of the HtmlSanitizer does not meet or exceed this value,
+ * sanitization will be deemed untrustworthy and emails will be displayed in a sandbox that does
+ * not allow script execution.
+ */
+ public int getRequiredSanitizerVersionNumber() {
+ return getSharedPreferences().getInt(PreferenceKeys.REQUIRED_SANITIZER_VERSION_NUMBER, 1);
+ }
+
+ /**
+ * @param versionNumber the minimum version number of the
+ * {@link com.android.mail.utils.HtmlSanitizer} which produces trusted output
+ */
+ public void setRequiredSanitizerVersionNumber(int versionNumber) {
+ getEditor().putInt(PreferenceKeys.REQUIRED_SANITIZER_VERSION_NUMBER, versionNumber).apply();
+ }
}
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 7f22bca..a280c55 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -238,7 +238,7 @@
/**
* Whether the server sends us sanitized HTML (guaranteed to not contain malicious HTML).
*/
- public static final int SANITIZED_HTML = 0x0080;
+ public static final int SERVER_SANITIZED_HTML = 0x0080;
/**
* Whether the server allows synchronization of draft messages. This does NOT require
* SYNCABLE_FOLDERS to be set.
@@ -316,6 +316,10 @@
* Whether the account supports nested folders
*/
public static final int NESTED_FOLDERS = 0x800000;
+ /**
+ * Whether the client is permitted to sanitize HTML for this account.
+ */
+ public static final int CLIENT_SANITIZED_HTML = 0x1000000;
}
public static final class AccountColumns implements BaseColumns {
diff --git a/src/com/android/mail/providers/protos/mock/MockUiProvider.java b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
index dcd4019..37a219b 100644
--- a/src/com/android/mail/providers/protos/mock/MockUiProvider.java
+++ b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
@@ -318,7 +318,7 @@
AccountCapabilities.MUTE |
AccountCapabilities.SERVER_SEARCH |
AccountCapabilities.FOLDER_SERVER_SEARCH |
- AccountCapabilities.SANITIZED_HTML |
+ AccountCapabilities.SERVER_SANITIZED_HTML |
AccountCapabilities.DRAFT_SYNCHRONIZATION |
AccountCapabilities.MULTIPLE_FROM_ADDRESSES |
AccountCapabilities.SMART_REPLY |
diff --git a/src/com/android/mail/utils/HtmlSanitizer.java b/src/com/android/mail/utils/HtmlSanitizer.java
index 976bdaa..da29345 100644
--- a/src/com/android/mail/utils/HtmlSanitizer.java
+++ b/src/com/android/mail/utils/HtmlSanitizer.java
@@ -44,6 +44,17 @@
* or comparable.
*/
public final class HtmlSanitizer {
+
+ /**
+ * This version number should be bumped each time a meaningful change is made to this sanitizer
+ * configuration which influences its output. It is compared against a minimum target version
+ * number. If it meets or exceeds the minimum target version, the result of the sanitizer is
+ * free to be shown in a standard webview. If it does not meet the minimum target version then
+ * the sanitized output is deemed untrustworthy and is shown in a sandboxed webview with
+ * javascript execution disabled.
+ */
+ public static final int VERSION = 1;
+
private static final String LOG_TAG = LogTag.getLogTag();
/**
@@ -90,7 +101,7 @@
final String value = attrs.remove(idIndex + 1);
attrs.remove(idIndex);
- // AOL uses a specifc id value to indicate quoted text
+ // AOL uses a specific id value to indicate quoted text
showHideQuotedText = value.startsWith("AOLMsgPart");
}