summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/BaseBundle.java6
-rw-r--r--core/tests/coretests/src/android/os/BundleTest.java63
2 files changed, 67 insertions, 2 deletions
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 0418a4bb9f80..b599028ccb9b 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -438,8 +438,11 @@ public class BaseBundle {
map.ensureCapacity(count);
}
try {
+ // recycleParcel being false implies that we do not own the parcel. In this case, do
+ // not use lazy values to be safe, as the parcel could be recycled outside of our
+ // control.
recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative,
- /* lazy */ true, mClassLoader);
+ /* lazy */ recycleParcel, mClassLoader);
} catch (BadParcelableException e) {
if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
@@ -1845,7 +1848,6 @@ public class BaseBundle {
// bundle immediately; neither of which is obvious.
synchronized (this) {
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle);
- unparcel(/* itemwise */ true);
}
return;
}
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index a3bda8b23f30..0fa5ec33749f 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -409,6 +409,69 @@ public class BundleTest {
}
@Test
+ public void readFromParcel_withLazyValues_copiesUnderlyingParcel() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+
+ Bundle testBundle = new Bundle();
+ testBundle.setClassLoader(getClass().getClassLoader());
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should have been copied
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isEqualTo("value");
+ assertThat(testBundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable);
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_whenThrowingAndNotDefusing_throws() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle testBundle = new Bundle();
+ assertThrows(BadParcelableException.class,
+ () -> testBundle.readFromParcel(parcelledBundle));
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_whenThrowingAndDefusing_returnsNull() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle.setShouldDefuse(true);
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should not be referenced
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isNull();
+ assertThat(testBundle.<Parcelable>getParcelable("key")).isNull();
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_withoutLazyObject_returnsValue() {
+ Bundle bundle = new Bundle();
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should not be referenced
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isEqualTo("value");
+ }
+
+ @Test
public void partialDeserialization_whenNotDefusing_throws() throws Exception {
Bundle.setShouldDefuse(false);
Bundle bundle = getMalformedBundle();