diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-22 14:53:18 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-05-22 14:53:18 -0700 |
commit | 9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a (patch) | |
tree | d00f0230d2e178a2f1aca915766f0901cc2262f8 | |
parent | ccf1ab64846112846c0bcd7fc4a623f55588ee46 (diff) | |
parent | d50a458bb291801ab9fdc119301bc7b84b42a6e3 (diff) | |
download | frameworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.zip frameworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.tar.gz frameworks_base-9f7d60cbfaa40bd78c0f4d5d4e3b8e8cf257e87a.tar.bz2 |
am d50a458b: Merge change 2351 into donut
Merge commit 'd50a458bb291801ab9fdc119301bc7b84b42a6e3'
* commit 'd50a458bb291801ab9fdc119301bc7b84b42a6e3':
Fix a major bug in Bundle when unparcelling from AIDL.
-rw-r--r-- | core/java/android/os/Bundle.java | 68 | ||||
-rw-r--r-- | core/java/android/os/Parcel.java | 68 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 8 |
3 files changed, 69 insertions, 75 deletions
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index b669fa2..a91655f 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -78,6 +78,10 @@ public final class Bundle implements Parcelable, Cloneable { readFromParcel(parcelledData); } + /* package */ Bundle(Parcel parcelledData, int length) { + readFromParcelInner(parcelledData, length); + } + /** * Constructs a new, empty Bundle that uses a specific ClassLoader for * instantiating Parcelable and Serializable objects. @@ -155,13 +159,14 @@ public final class Bundle implements Parcelable, Cloneable { return; } - mParcelledData.setDataPosition(0); - Bundle b = mParcelledData.readBundleUnpacked(mClassLoader); - mMap = b.mMap; - - mHasFds = mParcelledData.hasFileDescriptors(); - mFdsKnown = true; - + int N = mParcelledData.readInt(); + if (N < 0) { + return; + } + if (mMap == null) { + mMap = new HashMap<String, Object>(); + } + mParcelledData.readMapInternal(mMap, N, mClassLoader); mParcelledData.recycle(); mParcelledData = null; } @@ -1427,7 +1432,25 @@ public final class Bundle implements Parcelable, Cloneable { * @param parcel The parcel to copy this bundle to. */ public void writeToParcel(Parcel parcel, int flags) { - parcel.writeBundle(this); + if (mParcelledData != null) { + int length = mParcelledData.dataSize(); + parcel.writeInt(length); + parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' + parcel.appendFrom(mParcelledData, 0, length); + } else { + parcel.writeInt(-1); // dummy, will hold length + parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' + + int oldPos = parcel.dataPosition(); + parcel.writeMapInternal(mMap); + int newPos = parcel.dataPosition(); + + // Backpatch length + parcel.setDataPosition(oldPos - 8); + int length = newPos - oldPos; + parcel.writeInt(length); + parcel.setDataPosition(newPos); + } } /** @@ -1436,8 +1459,33 @@ public final class Bundle implements Parcelable, Cloneable { * @param parcel The parcel to overwrite this bundle from. */ public void readFromParcel(Parcel parcel) { - mParcelledData = parcel; - mHasFds = mParcelledData.hasFileDescriptors(); + int length = parcel.readInt(); + if (length < 0) { + throw new RuntimeException("Bad length in parcel: " + length); + } + readFromParcelInner(parcel, length); + } + + void readFromParcelInner(Parcel parcel, int length) { + int magic = parcel.readInt(); + if (magic != 0x4C444E42) { + //noinspection ThrowableInstanceNeverThrown + String st = Log.getStackTraceString(new RuntimeException()); + Log.e("Bundle", "readBundle: bad magic number"); + Log.e("Bundle", "readBundle: trace = " + st); + } + + // Advance within this Parcel + int offset = parcel.dataPosition(); + parcel.setDataPosition(offset + length); + + Parcel p = Parcel.obtain(); + p.setDataPosition(0); + p.appendFrom(parcel, offset, length); + p.setDataPosition(0); + + mParcelledData = p; + mHasFds = p.hasFileDescriptors(); mFdsKnown = true; } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 9a71f6e..6cfccee 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -457,7 +457,7 @@ public final class Parcel { * Flatten a Map into the parcel at the current dataPosition(), * growing dataCapacity() if needed. The Map keys must be String objects. */ - private void writeMapInternal(Map<String,Object> val) { + /* package */ void writeMapInternal(Map<String,Object> val) { if (val == null) { writeInt(-1); return; @@ -480,23 +480,7 @@ public final class Parcel { return; } - if (val.mParcelledData != null) { - int length = val.mParcelledData.dataSize(); - appendFrom(val.mParcelledData, 0, length); - } else { - writeInt(-1); // dummy, will hold length - int oldPos = dataPosition(); - writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' - - writeMapInternal(val.mMap); - int newPos = dataPosition(); - - // Backpatch length - setDataPosition(oldPos - 4); - int length = newPos - oldPos; - writeInt(length); - setDataPosition(newPos); - } + val.writeToParcel(this, 0); } /** @@ -1352,27 +1336,12 @@ public final class Parcel { * Returns null if the previously written Bundle object was null. */ public final Bundle readBundle(ClassLoader loader) { - int offset = dataPosition(); int length = readInt(); if (length < 0) { return null; } - int magic = readInt(); - if (magic != 0x4C444E42) { - //noinspection ThrowableInstanceNeverThrown - String st = Log.getStackTraceString(new RuntimeException()); - Log.e("Bundle", "readBundle: bad magic number"); - Log.e("Bundle", "readBundle: trace = " + st); - } - - // Advance within this Parcel - setDataPosition(offset + length + 4); - - Parcel p = new Parcel(0); - p.setDataPosition(0); - p.appendFrom(this, offset, length + 4); - p.setDataPosition(0); - final Bundle bundle = new Bundle(p); + + final Bundle bundle = new Bundle(this, length); if (loader != null) { bundle.setClassLoader(loader); } @@ -1380,33 +1349,6 @@ public final class Parcel { } /** - * Read and return a new Bundle object from the parcel at the current - * dataPosition(). Returns null if the previously written Bundle object was - * null. The returned bundle will have its contents fully unpacked using - * the given ClassLoader. - */ - /* package */ Bundle readBundleUnpacked(ClassLoader loader) { - int length = readInt(); - if (length == -1) { - return null; - } - int magic = readInt(); - if (magic != 0x4C444E42) { - //noinspection ThrowableInstanceNeverThrown - String st = Log.getStackTraceString(new RuntimeException()); - Log.e("Bundle", "readBundleUnpacked: bad magic number"); - Log.e("Bundle", "readBundleUnpacked: trace = " + st); - } - Bundle m = new Bundle(loader); - int N = readInt(); - if (N < 0) { - return null; - } - readMapInternal(m.mMap, N, loader); - return m; - } - - /** * Read and return a byte[] object from the parcel. */ public final native byte[] createByteArray(); @@ -1998,7 +1940,7 @@ public final class Parcel { private native void init(int obj); private native void destroy(); - private void readMapInternal(Map outVal, int N, + /* package */ void readMapInternal(Map outVal, int N, ClassLoader loader) { while (N > 0) { Object key = readValue(loader); diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 0819c29..3747de6 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -409,12 +409,16 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len) mObjects[idx++] = off; mObjectsSize++; - const flat_binder_object* flat + flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(mData + off); acquire_object(proc, *flat, this); - // take note if the object is a file descriptor if (flat->type == BINDER_TYPE_FD) { + // If this is a file descriptor, we need to dup it so the + // new Parcel now owns its own fd, and can declare that we + // officially know we have fds. + flat->handle = dup(flat->handle); + flat->cookie = (void*)1; mHasFds = mFdsKnown = true; } } |