summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dianne Hackborn <hackbod@google.com> 2016-10-12 17:20:07 -0700
committer Dianne Hackborn <hackbod@google.com> 2016-10-12 18:17:58 -0700
commit851ec49de73913547a51476e9c80cccfd7c15572 (patch)
treed7b83c3c48bf94206da2342db60166d77f825ce8
parent5c8fc588508a5f4ecf6f19a9b014e6462eb2db23 (diff)
Fix issue #32125907: Intent.replaceUnsafeExtras() corrupts original bundle
We now recursively generate new Bundle objects if we need to do any stripping. Change-Id: I4ca7896a0771c25264591ae7c79df85816d630d4
-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;
}
/**