Merge "Fix issue #16794553: Duplicate ArrayMap entries in Bundle..." into klp-dev
This commit is contained in:
@@ -599,7 +599,7 @@ public final class Parcel {
|
||||
* Flatten an ArrayMap into the parcel at the current dataPosition(),
|
||||
* growing dataCapacity() if needed. The Map keys must be String objects.
|
||||
*/
|
||||
/* package */ void writeArrayMapInternal(ArrayMap<String,Object> val) {
|
||||
/* package */ void writeArrayMapInternal(ArrayMap<String, Object> val) {
|
||||
if (val == null) {
|
||||
writeInt(-1);
|
||||
return;
|
||||
@@ -614,7 +614,7 @@ public final class Parcel {
|
||||
int startPos;
|
||||
for (int i=0; i<N; i++) {
|
||||
if (DEBUG_ARRAY_MAP) startPos = dataPosition();
|
||||
writeValue(val.keyAt(i));
|
||||
writeString(val.keyAt(i));
|
||||
writeValue(val.valueAt(i));
|
||||
if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + " "
|
||||
+ (dataPosition()-startPos) + " bytes: key=0x"
|
||||
@@ -623,6 +623,13 @@ public final class Parcel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide For testing only.
|
||||
*/
|
||||
public void writeArrayMap(ArrayMap<String, Object> val) {
|
||||
writeArrayMapInternal(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten a Bundle into the parcel at the current dataPosition(),
|
||||
* growing dataCapacity() if needed.
|
||||
@@ -2310,7 +2317,7 @@ public final class Parcel {
|
||||
int startPos;
|
||||
while (N > 0) {
|
||||
if (DEBUG_ARRAY_MAP) startPos = dataPosition();
|
||||
Object key = readValue(loader);
|
||||
String key = readString();
|
||||
Object value = readValue(loader);
|
||||
if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + " "
|
||||
+ (dataPosition()-startPos) + " bytes: key=0x"
|
||||
@@ -2318,6 +2325,7 @@ public final class Parcel {
|
||||
outVal.append(key, value);
|
||||
N--;
|
||||
}
|
||||
outVal.validate();
|
||||
}
|
||||
|
||||
/* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N,
|
||||
@@ -2328,7 +2336,7 @@ public final class Parcel {
|
||||
Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here);
|
||||
}
|
||||
while (N > 0) {
|
||||
Object key = readValue(loader);
|
||||
String key = readString();
|
||||
if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read safe #" + (N-1) + ": key=0x"
|
||||
+ (key != null ? key.hashCode() : 0) + " " + key);
|
||||
Object value = readValue(loader);
|
||||
@@ -2337,6 +2345,17 @@ public final class Parcel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide For testing only.
|
||||
*/
|
||||
public void readArrayMap(ArrayMap outVal, ClassLoader loader) {
|
||||
final int N = readInt();
|
||||
if (N < 0) {
|
||||
return;
|
||||
}
|
||||
readArrayMapInternal(outVal, N, loader);
|
||||
}
|
||||
|
||||
private void readListInternal(List outVal, int N,
|
||||
ClassLoader loader) {
|
||||
while (N > 0) {
|
||||
|
||||
@@ -493,6 +493,44 @@ public final class ArrayMap<K, V> implements Map<K, V> {
|
||||
mArray[index+1] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of the {@link #append} function can result in invalid array maps, in particular
|
||||
* an array map where the same key appears multiple times. This function verifies that
|
||||
* the array map is valid, throwing IllegalArgumentException if a problem is found. The
|
||||
* main use for this method is validating an array map after unpacking from an IPC, to
|
||||
* protect against malicious callers.
|
||||
* @hide
|
||||
*/
|
||||
public void validate() {
|
||||
final int N = mSize;
|
||||
if (N <= 1) {
|
||||
// There can't be dups.
|
||||
return;
|
||||
}
|
||||
int basehash = mHashes[0];
|
||||
int basei = 0;
|
||||
for (int i=1; i<N; i++) {
|
||||
int hash = mHashes[i];
|
||||
if (hash != basehash) {
|
||||
basehash = hash;
|
||||
basei = i;
|
||||
continue;
|
||||
}
|
||||
// We are in a run of entries with the same hash code. Go backwards through
|
||||
// the array to see if any keys are the same.
|
||||
final Object cur = mArray[i<<1];
|
||||
for (int j=i-1; j>=basei; j--) {
|
||||
final Object prev = mArray[j<<1];
|
||||
if (cur == prev) {
|
||||
throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur);
|
||||
}
|
||||
if (cur != null && prev != null && cur.equals(prev)) {
|
||||
throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var>
|
||||
* @param array The array whose contents are to be retrieved.
|
||||
|
||||
Reference in New Issue
Block a user