Verify Parcel object list does not get double freed after a setDataSize
Also clean up a commented out line in IParcelExceptionService.aidl
Bug: 134168436
Test: atest CtsOsTestCases:ParcelTest#testObjectDoubleFree
Change-Id: I8300423fd4351add8db27d1c4586577c98773c8a
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index d706470..765c8ef 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -88,6 +88,10 @@
android:name="android.os.cts.ParcelExceptionService"
android:process=":remote"
android:exported="true" />
+ <service
+ android:name="android.os.cts.ParcelTest$ParcelObjectFreeService"
+ android:process=":remote"
+ android:exported="true" />
<service android:name="android.os.cts.LocalService">
<intent-filter>
diff --git a/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
index ce7af6d..58d791c 100644
--- a/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
+++ b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
@@ -18,6 +18,5 @@
import android.os.cts.ExceptionalParcelable;
interface IParcelExceptionService {
-//parcelable android.os.cts.ExceptionalParcelable;
ExceptionalParcelable writeBinderThrowException();
}
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 77d325c..0287b7a 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -28,6 +28,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -3368,4 +3369,68 @@
assertNull("Binder should have been overwritten by the exception",
reply.readStrongBinder());
}
+
+ public static class ParcelObjectFreeService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new Binder();
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Parcel parcel = Parcel.obtain();
+
+ // Construct parcel with object in it.
+ parcel.writeInt(1);
+ final int pos = parcel.dataPosition();
+ parcel.writeStrongBinder(new Binder());
+
+ // wipe out the object by setting data size
+ parcel.setDataSize(pos);
+
+ // recycle the parcel. This should not cause a native segfault
+ parcel.recycle();
+ }
+
+ public static class Connection extends AbstractFuture<IBinder>
+ implements ServiceConnection {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public IBinder get() throws InterruptedException, ExecutionException {
+ try {
+ return get(5, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ return null;
+ }
+ }
+ }
+ }
+
+ public void testObjectDoubleFree() throws Exception {
+
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "android.os.cts", "android.os.cts.ParcelTest$ParcelObjectFreeService"));
+
+ final ParcelObjectFreeService.Connection connection =
+ new ParcelObjectFreeService.Connection();
+
+ mContext.startService(intent);
+ assertTrue(mContext.bindService(intent, connection,
+ Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
+
+ assertNotNull("Service should have started without crashing.", connection.get());
+ }
}