summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dianne Hackborn <hackbod@google.com> 2016-10-13 20:21:23 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-10-13 20:21:25 +0000
commit33e56a9e1ff122e28e3da40e6ced709a353222a4 (patch)
tree37779f0c460bba1dbccd7b334197b0aebd517951
parentcba436b312f1bf6890be1366843109eebdc1d229 (diff)
parent851ec49de73913547a51476e9c80cccfd7c15572 (diff)
Merge "Fix issue #32125907: Intent.replaceUnsafeExtras() corrupts original bundle" into nyc-mr1-dev
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/os/Bundle.java34
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;
}
/**