Merge change 2351 into donut
* changes: Fix a major bug in Bundle when unparcelling from AIDL.
This commit is contained in:
@@ -78,6 +78,10 @@ public final class Bundle implements Parcelable, Cloneable {
|
|||||||
readFromParcel(parcelledData);
|
readFromParcel(parcelledData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ Bundle(Parcel parcelledData, int length) {
|
||||||
|
readFromParcelInner(parcelledData, length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new, empty Bundle that uses a specific ClassLoader for
|
* Constructs a new, empty Bundle that uses a specific ClassLoader for
|
||||||
* instantiating Parcelable and Serializable objects.
|
* instantiating Parcelable and Serializable objects.
|
||||||
@@ -155,13 +159,14 @@ public final class Bundle implements Parcelable, Cloneable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mParcelledData.setDataPosition(0);
|
int N = mParcelledData.readInt();
|
||||||
Bundle b = mParcelledData.readBundleUnpacked(mClassLoader);
|
if (N < 0) {
|
||||||
mMap = b.mMap;
|
return;
|
||||||
|
}
|
||||||
mHasFds = mParcelledData.hasFileDescriptors();
|
if (mMap == null) {
|
||||||
mFdsKnown = true;
|
mMap = new HashMap<String, Object>();
|
||||||
|
}
|
||||||
|
mParcelledData.readMapInternal(mMap, N, mClassLoader);
|
||||||
mParcelledData.recycle();
|
mParcelledData.recycle();
|
||||||
mParcelledData = null;
|
mParcelledData = null;
|
||||||
}
|
}
|
||||||
@@ -1427,7 +1432,25 @@ public final class Bundle implements Parcelable, Cloneable {
|
|||||||
* @param parcel The parcel to copy this bundle to.
|
* @param parcel The parcel to copy this bundle to.
|
||||||
*/
|
*/
|
||||||
public void writeToParcel(Parcel parcel, int flags) {
|
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.
|
* @param parcel The parcel to overwrite this bundle from.
|
||||||
*/
|
*/
|
||||||
public void readFromParcel(Parcel parcel) {
|
public void readFromParcel(Parcel parcel) {
|
||||||
mParcelledData = parcel;
|
int length = parcel.readInt();
|
||||||
mHasFds = mParcelledData.hasFileDescriptors();
|
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;
|
mFdsKnown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ public final class Parcel {
|
|||||||
* Flatten a Map into the parcel at the current dataPosition(),
|
* Flatten a Map into the parcel at the current dataPosition(),
|
||||||
* growing dataCapacity() if needed. The Map keys must be String objects.
|
* 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) {
|
if (val == null) {
|
||||||
writeInt(-1);
|
writeInt(-1);
|
||||||
return;
|
return;
|
||||||
@@ -480,23 +480,7 @@ public final class Parcel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.mParcelledData != null) {
|
val.writeToParcel(this, 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1352,60 +1336,18 @@ public final class Parcel {
|
|||||||
* Returns null if the previously written Bundle object was null.
|
* Returns null if the previously written Bundle object was null.
|
||||||
*/
|
*/
|
||||||
public final Bundle readBundle(ClassLoader loader) {
|
public final Bundle readBundle(ClassLoader loader) {
|
||||||
int offset = dataPosition();
|
|
||||||
int length = readInt();
|
int length = readInt();
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int magic = readInt();
|
|
||||||
if (magic != 0x4C444E42) {
|
final Bundle bundle = new Bundle(this, length);
|
||||||
//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);
|
|
||||||
if (loader != null) {
|
if (loader != null) {
|
||||||
bundle.setClassLoader(loader);
|
bundle.setClassLoader(loader);
|
||||||
}
|
}
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Read and return a byte[] object from the parcel.
|
||||||
*/
|
*/
|
||||||
@@ -1998,7 +1940,7 @@ public final class Parcel {
|
|||||||
private native void init(int obj);
|
private native void init(int obj);
|
||||||
private native void destroy();
|
private native void destroy();
|
||||||
|
|
||||||
private void readMapInternal(Map outVal, int N,
|
/* package */ void readMapInternal(Map outVal, int N,
|
||||||
ClassLoader loader) {
|
ClassLoader loader) {
|
||||||
while (N > 0) {
|
while (N > 0) {
|
||||||
Object key = readValue(loader);
|
Object key = readValue(loader);
|
||||||
|
|||||||
@@ -409,12 +409,16 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
|
|||||||
mObjects[idx++] = off;
|
mObjects[idx++] = off;
|
||||||
mObjectsSize++;
|
mObjectsSize++;
|
||||||
|
|
||||||
const flat_binder_object* flat
|
flat_binder_object* flat
|
||||||
= reinterpret_cast<flat_binder_object*>(mData + off);
|
= reinterpret_cast<flat_binder_object*>(mData + off);
|
||||||
acquire_object(proc, *flat, this);
|
acquire_object(proc, *flat, this);
|
||||||
|
|
||||||
// take note if the object is a file descriptor
|
|
||||||
if (flat->type == BINDER_TYPE_FD) {
|
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;
|
mHasFds = mFdsKnown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user