OSDN Git Service

Preventing data overwirte in a Parcel
authorSunny Goyal <sunnygoyal@google.com>
Thu, 21 Sep 2017 18:08:34 +0000 (11:08 -0700)
committerSunny Goyal <sunnygoyal@google.com>
Thu, 21 Sep 2017 18:32:13 +0000 (11:32 -0700)
Test: am instrument -w -e class android.widget.RemoteViewsTest com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
Bug: 65576228
Change-Id: Ia1f072c1451eba3c6c13833c5a813e754df901e2

core/java/android/widget/RemoteViews.java
core/tests/coretests/src/android/widget/RemoteViewsTest.java

index 7903d6f..1653afd 100644 (file)
@@ -2339,20 +2339,12 @@ public class RemoteViews implements Parcelable, Filter {
         }
 
         if (src.mActions != null) {
-            mActions = new ArrayList<>();
-
             Parcel p = Parcel.obtain();
-            int count = src.mActions.size();
-            for (int i = 0; i < count; i++) {
-                p.setDataPosition(0);
-                Action a = src.mActions.get(i);
-                a.writeToParcel(
-                        p, a.hasSameAppInfo(mApplication) ? PARCELABLE_ELIDE_DUPLICATES : 0);
-                p.setDataPosition(0);
-                // Since src is already in memory, we do not care about stack overflow as it has
-                // already been read once.
-                mActions.add(getActionFromParcel(p, 0));
-            }
+            writeActionsToParcel(p);
+            p.setDataPosition(0);
+            // Since src is already in memory, we do not care about stack overflow as it has
+            // already been read once.
+            readActionsFromParcel(p, 0);
             p.recycle();
         }
 
@@ -2393,13 +2385,7 @@ public class RemoteViews implements Parcelable, Filter {
             mLayoutId = parcel.readInt();
             mIsWidgetCollectionChild = parcel.readInt() == 1;
 
-            int count = parcel.readInt();
-            if (count > 0) {
-                mActions = new ArrayList<>(count);
-                for (int i = 0; i < count; i++) {
-                    mActions.add(getActionFromParcel(parcel, depth));
-                }
-            }
+            readActionsFromParcel(parcel, depth);
         } else {
             // MODE_HAS_LANDSCAPE_AND_PORTRAIT
             mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth);
@@ -2410,6 +2396,16 @@ public class RemoteViews implements Parcelable, Filter {
         mReapplyDisallowed = parcel.readInt() == 0;
     }
 
+    private void readActionsFromParcel(Parcel parcel, int depth) {
+        int count = parcel.readInt();
+        if (count > 0) {
+            mActions = new ArrayList<>(count);
+            for (int i = 0; i < count; i++) {
+                mActions.add(getActionFromParcel(parcel, depth));
+            }
+        }
+    }
+
     private Action getActionFromParcel(Parcel parcel, int depth) {
         int tag = parcel.readInt();
         switch (tag) {
@@ -3696,18 +3692,7 @@ public class RemoteViews implements Parcelable, Filter {
             }
             dest.writeInt(mLayoutId);
             dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
-            int count;
-            if (mActions != null) {
-                count = mActions.size();
-            } else {
-                count = 0;
-            }
-            dest.writeInt(count);
-            for (int i=0; i<count; i++) {
-                Action a = mActions.get(i);
-                a.writeToParcel(dest, a.hasSameAppInfo(mApplication)
-                        ? PARCELABLE_ELIDE_DUPLICATES : 0);
-            }
+            writeActionsToParcel(dest);
         } else {
             dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
             // We only write the bitmap cache if we are the root RemoteViews, as this cache
@@ -3722,6 +3707,21 @@ public class RemoteViews implements Parcelable, Filter {
         dest.writeInt(mReapplyDisallowed ? 1 : 0);
     }
 
+    private void writeActionsToParcel(Parcel parcel) {
+        int count;
+        if (mActions != null) {
+            count = mActions.size();
+        } else {
+            count = 0;
+        }
+        parcel.writeInt(count);
+        for (int i = 0; i < count; i++) {
+            Action a = mActions.get(i);
+            a.writeToParcel(parcel, a.hasSameAppInfo(mApplication)
+                    ? PARCELABLE_ELIDE_DUPLICATES : 0);
+        }
+    }
+
     private static ApplicationInfo getApplicationInfo(String packageName, int userId) {
         if (packageName == null) {
             return null;
index d26437e..ddf9876 100644 (file)
@@ -20,7 +20,9 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
@@ -382,4 +384,19 @@ public class RemoteViewsTest {
         RemoteViews.CREATOR.createFromParcel(p);
         p.recycle();
     }
+
+    @Test
+    public void copyWithBinders() throws Exception {
+        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
+        for (int i = 1; i < 10; i++) {
+            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0,
+                    new Intent("android.widget.RemoteViewsTest_" + i), PendingIntent.FLAG_ONE_SHOT);
+            views.setOnClickPendingIntent(i, pi);
+        }
+        try {
+            new RemoteViews(views);
+        } catch (Throwable t) {
+            throw new Exception(t);
+        }
+    }
 }