diff options
| author | 2016-10-13 20:21:23 +0000 | |
|---|---|---|
| committer | 2016-10-13 20:21:25 +0000 | |
| commit | 33e56a9e1ff122e28e3da40e6ced709a353222a4 (patch) | |
| tree | 37779f0c460bba1dbccd7b334197b0aebd517951 | |
| parent | cba436b312f1bf6890be1366843109eebdc1d229 (diff) | |
| parent | 851ec49de73913547a51476e9c80cccfd7c15572 (diff) | |
Merge "Fix issue #32125907: Intent.replaceUnsafeExtras() corrupts original bundle" into nyc-mr1-dev
| -rw-r--r-- | core/java/android/content/Intent.java | 2 | ||||
| -rw-r--r-- | core/java/android/os/Bundle.java | 34 |
2 files changed, 30 insertions, 6 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index cf6880a981f4..c6aaa48ddad0 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -6573,7 +6573,7 @@ public class Intent implements Parcelable, Cloneable { */ public void removeUnsafeExtras() { if (mExtras != null) { - mExtras.filterValues(); + mExtras = mExtras.filterValues(); } } diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index ca64a965af0b..62fa7721702e 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -309,25 +309,49 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * Filter values in Bundle to only basic types. * @hide */ - public void filterValues() { + public Bundle filterValues() { unparcel(); + Bundle bundle = this; if (mMap != null) { - for (int i = mMap.size() - 1; i >= 0; i--) { - Object value = mMap.valueAt(i); + ArrayMap<String, Object> map = mMap; + for (int i = map.size() - 1; i >= 0; i--) { + Object value = map.valueAt(i); if (PersistableBundle.isValidType(value)) { continue; } if (value instanceof Bundle) { - ((Bundle)value).filterValues(); + Bundle newBundle = ((Bundle)value).filterValues(); + if (newBundle != value) { + if (map == mMap) { + // The filter had to generate a new bundle, but we have not yet + // created a new one here. Do that now. + bundle = new Bundle(this); + // Note the ArrayMap<> constructor is guaranteed to generate + // a new object with items in the same order as the original. + map = bundle.mMap; + } + // Replace this current entry with the new child bundle. + map.setValueAt(i, newBundle); + } + continue; } if (value.getClass().getName().startsWith("android.")) { continue; } - mMap.removeAt(i); + if (map == mMap) { + // This is the first time we have had to remove something, that means we + // need to switch to a new Bundle. + bundle = new Bundle(this); + // Note the ArrayMap<> constructor is guaranteed to generate + // a new object with items in the same order as the original. + map = bundle.mMap; + } + map.removeAt(i); } } mFlags |= FLAG_HAS_FDS_KNOWN; mFlags &= ~FLAG_HAS_FDS; + return bundle; } /** |