Skip to content

Commit 26ead61

Browse files
authored
[LANG-1814] ArrayUtils.subarray(..) may overflow index arithmetic and violate contract for extreme index values #1585
1 parent 87538eb commit 26ead61

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/main/java/org/apache/commons/lang3/ArrayUtils.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8088,7 +8088,7 @@ public static boolean[] subarray(final boolean[] array, int startIndexInclusive,
80888088
return null;
80898089
}
80908090
startIndexInclusive = max0(startIndexInclusive);
8091-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8091+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
80928092
final int newSize = endIndexExclusive - startIndexInclusive;
80938093
if (newSize <= 0) {
80948094
return EMPTY_BOOLEAN_ARRAY;
@@ -8115,7 +8115,7 @@ public static byte[] subarray(final byte[] array, int startIndexInclusive, int e
81158115
return null;
81168116
}
81178117
startIndexInclusive = max0(startIndexInclusive);
8118-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8118+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
81198119
final int newSize = endIndexExclusive - startIndexInclusive;
81208120
if (newSize <= 0) {
81218121
return EMPTY_BYTE_ARRAY;
@@ -8142,7 +8142,7 @@ public static char[] subarray(final char[] array, int startIndexInclusive, int e
81428142
return null;
81438143
}
81448144
startIndexInclusive = max0(startIndexInclusive);
8145-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8145+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
81468146
final int newSize = endIndexExclusive - startIndexInclusive;
81478147
if (newSize <= 0) {
81488148
return EMPTY_CHAR_ARRAY;
@@ -8169,7 +8169,7 @@ public static double[] subarray(final double[] array, int startIndexInclusive, i
81698169
return null;
81708170
}
81718171
startIndexInclusive = max0(startIndexInclusive);
8172-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8172+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
81738173
final int newSize = endIndexExclusive - startIndexInclusive;
81748174
if (newSize <= 0) {
81758175
return EMPTY_DOUBLE_ARRAY;
@@ -8196,7 +8196,7 @@ public static float[] subarray(final float[] array, int startIndexInclusive, int
81968196
return null;
81978197
}
81988198
startIndexInclusive = max0(startIndexInclusive);
8199-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8199+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
82008200
final int newSize = endIndexExclusive - startIndexInclusive;
82018201
if (newSize <= 0) {
82028202
return EMPTY_FLOAT_ARRAY;
@@ -8223,7 +8223,7 @@ public static int[] subarray(final int[] array, int startIndexInclusive, int end
82238223
return null;
82248224
}
82258225
startIndexInclusive = max0(startIndexInclusive);
8226-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8226+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
82278227
final int newSize = endIndexExclusive - startIndexInclusive;
82288228
if (newSize <= 0) {
82298229
return EMPTY_INT_ARRAY;
@@ -8250,7 +8250,7 @@ public static long[] subarray(final long[] array, int startIndexInclusive, int e
82508250
return null;
82518251
}
82528252
startIndexInclusive = max0(startIndexInclusive);
8253-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8253+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
82548254
final int newSize = endIndexExclusive - startIndexInclusive;
82558255
if (newSize <= 0) {
82568256
return EMPTY_LONG_ARRAY;
@@ -8277,7 +8277,7 @@ public static short[] subarray(final short[] array, int startIndexInclusive, int
82778277
return null;
82788278
}
82798279
startIndexInclusive = max0(startIndexInclusive);
8280-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8280+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
82818281
final int newSize = endIndexExclusive - startIndexInclusive;
82828282
if (newSize <= 0) {
82838283
return EMPTY_SHORT_ARRAY;
@@ -8314,7 +8314,7 @@ public static <T> T[] subarray(final T[] array, int startIndexInclusive, int end
83148314
return null;
83158315
}
83168316
startIndexInclusive = max0(startIndexInclusive);
8317-
endIndexExclusive = Math.min(endIndexExclusive, array.length);
8317+
endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
83188318
final int newSize = endIndexExclusive - startIndexInclusive;
83198319
final Class<T> type = getComponentType(array);
83208320
if (newSize <= 0) {

src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5618,6 +5618,7 @@ void testSubarrayBoolean() {
56185618
assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_BOOLEAN_ARRAY, 1, 2),
56195619
"empty array, object test");
56205620
assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5621+
assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, object test");
56215622
assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
56225623
assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 8733, 4),
56235624
"start overshoot, any end, object test");
@@ -5649,6 +5650,7 @@ void testSubarrayByte() {
56495650
// empty-return tests
56505651
assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_BYTE_ARRAY, 1, 2), "empty array, object test");
56515652
assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5653+
assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
56525654
assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
56535655
assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 8733, 4), "start overshoot, any end, object test");
56545656
// array type tests
@@ -5677,6 +5679,7 @@ void testSubarrayDouble() {
56775679
// empty-return tests
56785680
assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_DOUBLE_ARRAY, 1, 2), "empty array, object test");
56795681
assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5682+
assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
56805683
assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
56815684
assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 8733, 4), "start overshoot, any end, object test");
56825685
// array type tests
@@ -5705,6 +5708,7 @@ void testSubarrayFloat() {
57055708
// empty-return tests
57065709
assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_FLOAT_ARRAY, 1, 2), "empty array, object test");
57075710
assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5711+
assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
57085712
assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
57095713
assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 8733, 4), "start overshoot, any end, object test");
57105714
// array type tests
@@ -5733,6 +5737,7 @@ void testSubarrayInt() {
57335737
// empty-return tests
57345738
assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_INT_ARRAY, 1, 2), "empty array, object test");
57355739
assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5740+
assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
57365741
assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
57375742
assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 8733, 4), "start overshoot, any end, object test");
57385743
// array type tests
@@ -5781,6 +5786,7 @@ void testSubarrayLong() {
57815786
"empty array, object test");
57825787

57835788
assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5789+
assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
57845790

57855791
assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
57865792

@@ -5808,6 +5814,7 @@ void testSubarrayObject() {
58085814
assertNull(ArrayUtils.subarray(nullArray, 0, 3), "null input");
58095815
assertEquals("", StringUtils.join(ArrayUtils.subarray(ArrayUtils.EMPTY_OBJECT_ARRAY, 1, 2)), "empty array");
58105816
assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 4, 2)), "start > end");
5817+
assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 2147483647, -2147483648)), "start > end");
58115818
assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 3, 3)), "start == end");
58125819
assertEquals("abcd", StringUtils.join(ArrayUtils.subarray(objectArray, -2, 4)), "start undershoot, normal end");
58135820
assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 33, 4)), "start overshoot, any end");
@@ -5860,6 +5867,7 @@ void testSubarrayShort() {
58605867
assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_SHORT_ARRAY, 1, 2),
58615868
"empty array, object test");
58625869
assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5870+
assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
58635871
assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
58645872
assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 8733, 4),
58655873
"start overshoot, any end, object test");
@@ -5895,6 +5903,7 @@ void testSubarrChar() {
58955903

58965904
assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(ArrayUtils.EMPTY_CHAR_ARRAY, 1, 2), "empty array, object test");
58975905
assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 4, 1), "start > end, object test");
5906+
assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 2147483647, -2147483648), "start > end, possible overflow");
58985907
assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 3, 3), "start == end, object test");
58995908
assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 8733, 4), "start overshoot, any end, object test");
59005909

0 commit comments

Comments
 (0)