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
This commit is contained in:
Dianne Hackborn
2016-10-12 17:20:07 -07:00
parent 5c8fc58850
commit 851ec49de7
2 changed files with 30 additions and 6 deletions

View File

@@ -6573,7 +6573,7 @@ public class Intent implements Parcelable, Cloneable {
*/
public void removeUnsafeExtras() {
if (mExtras != null) {
mExtras.filterValues();
mExtras = mExtras.filterValues();
}
}

View File

@@ -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;
}
/**