summaryrefslogtreecommitdiff
path: root/core/java/android/util/ArrayMap.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2014-08-13 15:39:50 -0700
committerDianne Hackborn <hackbod@google.com>2014-08-13 17:24:45 -0700
commit9c3e74f1f77d3b29ad47d2c74b0a0061e67c76f1 (patch)
tree7a5d38c069fcdad9072829fbeca7c79ee8bbcaa9 /core/java/android/util/ArrayMap.java
parent57e383b1cc72aea93b0041d69afa31a02597338a (diff)
Fix issue #16794553: Duplicate ArrayMap entries in Bundle...
...can lead to launching of un-exported activities We now validate the array map after unparcelling to make sure there are no duplicate keys. And to make up for the performance overhead this introduces, I switched the parcelling/unparcelling code to write keys as explicit string objects rather than generic values. There was no reason to use generic values since the write method itself only accepts an array map with String keys. Change-Id: I57bda9eb79ceaaa9c1b94ad49d9e462b52102149
Diffstat (limited to 'core/java/android/util/ArrayMap.java')
-rw-r--r--core/java/android/util/ArrayMap.java38
1 files changed, 38 insertions, 0 deletions
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 3bdd58ab3eb2..3889cb68129d 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -496,6 +496,44 @@ public final class ArrayMap<K, V> implements Map<K, V> {
}
/**
+ * 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.
*/