diff options
author | Jon Larimer <jlarimer@google.com> | 2015-01-29 18:12:01 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-29 18:12:01 +0000 |
commit | 2982d64802ed0d5b59130680c43485e9d7862e50 (patch) | |
tree | 2d45591cbb74b85eacb54954bbd8950c9aff8736 /core/java/android | |
parent | 76cdbb0475fe881c8e7320c277e5ea4848be5bff (diff) | |
parent | de9a76ed997c300a6c5f2f82c517719503af9045 (diff) | |
download | frameworks_base-2982d64802ed0d5b59130680c43485e9d7862e50.zip frameworks_base-2982d64802ed0d5b59130680c43485e9d7862e50.tar.gz frameworks_base-2982d64802ed0d5b59130680c43485e9d7862e50.tar.bz2 |
am de9a76ed: am fc731e6e: Merge "Fix ParceledListSlice to enforce the same concrete types among its elements." into jb-mr2-dev
* commit 'de9a76ed997c300a6c5f2f82c517719503af9045':
Fix ParceledListSlice to enforce the same concrete types among its elements.
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/content/pm/ParceledListSlice.java | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index 8a43472..335a45e 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -30,6 +30,12 @@ import java.util.List; * Transfer a large list of Parcelable objects across an IPC. Splits into * multiple transactions if needed. * + * Caveat: for efficiency and security, all elements must be the same concrete type. + * In order to avoid writing the class name of each object, we must ensure that + * each object is the same type, or else unparceling then reparceling the data may yield + * a different result if the class name encoded in the Parcelable is a Base type. + * See b/17671747. + * * @hide */ public class ParceledListSlice<T extends Parcelable> implements Parcelable { @@ -56,13 +62,25 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { if (N <= 0) { return; } + Parcelable.Creator<T> creator = p.readParcelableCreator(loader); + Class<?> listElementClass = null; + int i = 0; while (i < N) { if (p.readInt() == 0) { break; } - mList.add(p.readCreator(creator, loader)); + + final T parcelable = p.readCreator(creator, loader); + if (listElementClass == null) { + listElementClass = parcelable.getClass(); + } else { + verifySameType(listElementClass, parcelable.getClass()); + } + + mList.add(parcelable); + if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1)); i++; } @@ -82,7 +100,11 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { return; } while (i < N && reply.readInt() != 0) { - mList.add(reply.readCreator(creator, loader)); + final T parcelable = reply.readCreator(creator, loader); + verifySameType(listElementClass, parcelable.getClass()); + + mList.add(parcelable); + if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1)); i++; } @@ -91,6 +113,14 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { } } + private static void verifySameType(final Class<?> expected, final Class<?> actual) { + if (!actual.equals(expected)) { + throw new IllegalArgumentException("Can't unparcel type " + + actual.getName() + " in list of type " + + expected.getName()); + } + } + public List<T> getList() { return mList; } @@ -116,11 +146,16 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { dest.writeInt(N); if (DEBUG) Log.d(TAG, "Writing " + N + " items"); if (N > 0) { + final Class<?> listElementClass = mList.get(0).getClass(); dest.writeParcelableCreator(mList.get(0)); int i = 0; while (i < N && dest.dataSize() < MAX_FIRST_IPC_SIZE) { dest.writeInt(1); - mList.get(i).writeToParcel(dest, callFlags); + + final T parcelable = mList.get(i); + verifySameType(listElementClass, parcelable.getClass()); + parcelable.writeToParcel(dest, callFlags); + if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i)); i++; } @@ -137,7 +172,11 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N); while (i < N && reply.dataSize() < MAX_IPC_SIZE) { reply.writeInt(1); - mList.get(i).writeToParcel(reply, callFlags); + + final T parcelable = mList.get(i); + verifySameType(listElementClass, parcelable.getClass()); + parcelable.writeToParcel(reply, callFlags); + if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i)); i++; } |