From 17d453ea85703a5bc26c0669231be4d6f0d8bbac Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Tue, 5 Mar 2019 15:30:42 -0800 Subject: [PATCH] Checkng upper bound in *Array classes. *Array classes will now throw an IndexOutOfBoundsException if a caller tries to get or set a value for an index that's invalid based on the current size. Bug: 118339123 Test: atest CtsUtilTestCases Change-Id: Iddc9a0c7c89e0ac743b0380049527a1b2dfb434f --- core/java/android/util/ArrayMap.java | 21 +++++++++++++++++-- core/java/android/util/LongSparseArray.java | 19 ++++++++++++++--- .../android/util/LongSparseLongArray.java | 13 +++++++++--- core/java/android/util/SparseArray.java | 19 ++++++++++++++++- .../java/android/util/SparseBooleanArray.java | 19 ++++++++++++++++- core/java/android/util/SparseIntArray.java | 19 ++++++++++++++--- core/java/android/util/SparseLongArray.java | 8 +++++++ 7 files changed, 105 insertions(+), 13 deletions(-) diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index 436cb4ff7072c..e2af6f5ed102e 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -16,12 +16,12 @@ package android.util; -import libcore.util.EmptyArray; - import android.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; +import libcore.util.EmptyArray; + import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Map; @@ -453,6 +453,10 @@ public final class ArrayMap implements Map { * @return Returns the key stored at the given index. */ public K keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return (K)mArray[index << 1]; } @@ -462,6 +466,10 @@ public final class ArrayMap implements Map { * @return Returns the value stored at the given index. */ public V valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return (V)mArray[(index << 1) + 1]; } @@ -472,6 +480,10 @@ public final class ArrayMap implements Map { * @return Returns the previous value at the given index. */ public V setValueAt(int index, V value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } index = (index << 1) + 1; V old = (V)mArray[index]; mArray[index] = value; @@ -665,6 +677,11 @@ public final class ArrayMap implements Map { * @return Returns the value that was stored at this index. */ public V removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } + final Object old = mArray[(index << 1) + 1]; final int osize = mSize; final int nsize; diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java index cf49803a72251..e4de7045721b9 100644 --- a/core/java/android/util/LongSparseArray.java +++ b/core/java/android/util/LongSparseArray.java @@ -21,9 +21,6 @@ import com.android.internal.util.GrowingArrayUtils; import libcore.util.EmptyArray; -import java.util.Arrays; -import java.util.Objects; - /** * SparseArray mapping longs to Objects. Unlike a normal array of Objects, * there can be gaps in the indices. It is intended to be more memory efficient @@ -147,6 +144,10 @@ public class LongSparseArray implements Cloneable { * Removes the mapping at the specified index. */ public void removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mValues[index] != DELETED) { mValues[index] = DELETED; mGarbage = true; @@ -236,6 +237,10 @@ public class LongSparseArray implements Cloneable { * key.

*/ public long keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -256,6 +261,10 @@ public class LongSparseArray implements Cloneable { */ @SuppressWarnings("unchecked") public E valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -269,6 +278,10 @@ public class LongSparseArray implements Cloneable { * LongSparseArray stores. */ public void setValueAt(int index, E value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java index 8dcdb40262465..f167f009a942e 100644 --- a/core/java/android/util/LongSparseLongArray.java +++ b/core/java/android/util/LongSparseLongArray.java @@ -16,14 +16,13 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; -import java.util.Arrays; - /** * Map of {@code long} to {@code long}. Unlike a normal array of longs, there * can be gaps in the indices. It is intended to be more memory efficient than using a @@ -173,6 +172,10 @@ public class LongSparseLongArray implements Cloneable { * key.

*/ public long keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -188,6 +191,10 @@ public class LongSparseLongArray implements Cloneable { * associated with the largest key.

*/ public long valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index 89ea2d35fc2f4..67dfb02a0b954 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -16,10 +16,11 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; /** @@ -171,6 +172,10 @@ public class SparseArray implements Cloneable { * the behavior is undefined.

*/ public void removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mValues[index] != DELETED) { mValues[index] = DELETED; mGarbage = true; @@ -279,6 +284,10 @@ public class SparseArray implements Cloneable { * the behavior is undefined.

*/ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -302,6 +311,10 @@ public class SparseArray implements Cloneable { */ @SuppressWarnings("unchecked") public E valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -317,6 +330,10 @@ public class SparseArray implements Cloneable { *

For indices outside of the range 0...size()-1, the behavior is undefined.

*/ public void setValueAt(int index, E value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java index d4c40954bdd10..03fa1c996027c 100644 --- a/core/java/android/util/SparseBooleanArray.java +++ b/core/java/android/util/SparseBooleanArray.java @@ -16,10 +16,11 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; /** @@ -167,6 +168,10 @@ public class SparseBooleanArray implements Cloneable { * key.

*/ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -182,6 +187,10 @@ public class SparseBooleanArray implements Cloneable { * associated with the largest key.

*/ public boolean valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } @@ -189,11 +198,19 @@ public class SparseBooleanArray implements Cloneable { * Directly set the value at a particular index. */ public void setValueAt(int index, boolean value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mValues[index] = value; } /** @hide */ public void setKeyAt(int index, int key) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mKeys[index] = key; } diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 9e6bad1d9ae0b..c68dc4edcfb7c 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -16,14 +16,15 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import java.util.Arrays; - -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; +import java.util.Arrays; + /** * SparseIntArrays map integers to integers. Unlike a normal array of integers, * there can be gaps in the indices. It is intended to be more memory efficient @@ -171,6 +172,10 @@ public class SparseIntArray implements Cloneable { * key.

*/ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -186,6 +191,10 @@ public class SparseIntArray implements Cloneable { * associated with the largest key.

*/ public int valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } @@ -193,6 +202,10 @@ public class SparseIntArray implements Cloneable { * Directly set the value at a particular index. */ public void setValueAt(int index, int value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mValues[index] = value; } diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java index 81db2b7ff7153..37a92024f374b 100644 --- a/core/java/android/util/SparseLongArray.java +++ b/core/java/android/util/SparseLongArray.java @@ -182,6 +182,10 @@ public class SparseLongArray implements Cloneable { * key.

*/ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -197,6 +201,10 @@ public class SparseLongArray implements Cloneable { * associated with the largest key.

*/ public long valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; }