Loading core/java/android/os/BaseBundle.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -438,8 +438,11 @@ public class BaseBundle { map.ensureCapacity(count); map.ensureCapacity(count); } } try { 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, recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ true, mClassLoader); /* lazy */ recycleParcel, mClassLoader); } catch (BadParcelableException e) { } catch (BadParcelableException e) { if (sShouldDefuse) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Loading Loading @@ -1845,7 +1848,6 @@ public class BaseBundle { // bundle immediately; neither of which is obvious. // bundle immediately; neither of which is obvious. synchronized (this) { synchronized (this) { initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); unparcel(/* itemwise */ true); } } return; return; } } Loading core/tests/coretests/src/android/os/BundleTest.java +63 −0 Original line number Original line Diff line number Diff line Loading @@ -408,6 +408,69 @@ public class BundleTest { assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable); assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable); } } @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 @Test public void partialDeserialization_whenNotDefusing_throws() throws Exception { public void partialDeserialization_whenNotDefusing_throws() throws Exception { Bundle.setShouldDefuse(false); Bundle.setShouldDefuse(false); Loading Loading
core/java/android/os/BaseBundle.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -438,8 +438,11 @@ public class BaseBundle { map.ensureCapacity(count); map.ensureCapacity(count); } } try { 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, recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ true, mClassLoader); /* lazy */ recycleParcel, mClassLoader); } catch (BadParcelableException e) { } catch (BadParcelableException e) { if (sShouldDefuse) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Loading Loading @@ -1845,7 +1848,6 @@ public class BaseBundle { // bundle immediately; neither of which is obvious. // bundle immediately; neither of which is obvious. synchronized (this) { synchronized (this) { initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle); unparcel(/* itemwise */ true); } } return; return; } } Loading
core/tests/coretests/src/android/os/BundleTest.java +63 −0 Original line number Original line Diff line number Diff line Loading @@ -408,6 +408,69 @@ public class BundleTest { assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable); assertThat(bundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable); } } @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 @Test public void partialDeserialization_whenNotDefusing_throws() throws Exception { public void partialDeserialization_whenNotDefusing_throws() throws Exception { Bundle.setShouldDefuse(false); Bundle.setShouldDefuse(false); Loading