This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 26ead6134 [LANG-1814] ArrayUtils.subarray(..) may overflow index 
arithmetic and violate contract for extreme index values #1585
26ead6134 is described below

commit 26ead6134ad55bf1350e41f05f4d0cbe6d0be4be
Author: Ivan Ponomarev <[email protected]>
AuthorDate: Mon Jan 26 18:58:22 2026 +0000

    [LANG-1814] ArrayUtils.subarray(..) may overflow index arithmetic and 
violate contract for extreme index values #1585
---
 src/main/java/org/apache/commons/lang3/ArrayUtils.java | 18 +++++++++---------
 .../java/org/apache/commons/lang3/ArrayUtilsTest.java  |  9 +++++++++
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java 
b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
index 5cd2bdab6..6cd708582 100644
--- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
@@ -8088,7 +8088,7 @@ public static boolean[] subarray(final boolean[] array, 
int startIndexInclusive,
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_BOOLEAN_ARRAY;
@@ -8115,7 +8115,7 @@ public static byte[] subarray(final byte[] array, int 
startIndexInclusive, int e
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_BYTE_ARRAY;
@@ -8142,7 +8142,7 @@ public static char[] subarray(final char[] array, int 
startIndexInclusive, int e
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_CHAR_ARRAY;
@@ -8169,7 +8169,7 @@ public static double[] subarray(final double[] array, int 
startIndexInclusive, i
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_DOUBLE_ARRAY;
@@ -8196,7 +8196,7 @@ public static float[] subarray(final float[] array, int 
startIndexInclusive, int
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_FLOAT_ARRAY;
@@ -8223,7 +8223,7 @@ public static int[] subarray(final int[] array, int 
startIndexInclusive, int end
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_INT_ARRAY;
@@ -8250,7 +8250,7 @@ public static long[] subarray(final long[] array, int 
startIndexInclusive, int e
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_LONG_ARRAY;
@@ -8277,7 +8277,7 @@ public static short[] subarray(final short[] array, int 
startIndexInclusive, int
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         if (newSize <= 0) {
             return EMPTY_SHORT_ARRAY;
@@ -8314,7 +8314,7 @@ public static <T> T[] subarray(final T[] array, int 
startIndexInclusive, int end
             return null;
         }
         startIndexInclusive = max0(startIndexInclusive);
-        endIndexExclusive = Math.min(endIndexExclusive, array.length);
+        endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
         final int newSize = endIndexExclusive - startIndexInclusive;
         final Class<T> type = getComponentType(array);
         if (newSize <= 0) {
diff --git a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
index 1bf5f517d..bf3d3d398 100644
--- a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
@@ -5618,6 +5618,7 @@ void testSubarrayBoolean() {
         assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_BOOLEAN_ARRAY, 1, 2),
                 "empty array, object test");
         assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 
4, 1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, object test");
         assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 
3, 3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_BOOLEAN_ARRAY, ArrayUtils.subarray(array, 
8733, 4),
                 "start overshoot, any end, object test");
@@ -5649,6 +5650,7 @@ void testSubarrayByte() {
         // empty-return tests
         assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_BYTE_ARRAY, 1, 2), "empty array, object 
test");
         assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.subarray(array, 
8733, 4), "start overshoot, any end, object test");
         // array type tests
@@ -5677,6 +5679,7 @@ void testSubarrayDouble() {
         // empty-return tests
         assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_DOUBLE_ARRAY, 1, 2), "empty array, object 
test");
         assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 
4, 1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 
3, 3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_DOUBLE_ARRAY, ArrayUtils.subarray(array, 
8733, 4), "start overshoot, any end, object test");
         // array type tests
@@ -5705,6 +5708,7 @@ void testSubarrayFloat() {
         // empty-return tests
         assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_FLOAT_ARRAY, 1, 2), "empty array, object 
test");
         assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_FLOAT_ARRAY, ArrayUtils.subarray(array, 
8733, 4), "start overshoot, any end, object test");
         // array type tests
@@ -5733,6 +5737,7 @@ void testSubarrayInt() {
         // empty-return tests
         assertSame(ArrayUtils.EMPTY_INT_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_INT_ARRAY, 1, 2), "empty array, object 
test");
         assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_INT_ARRAY, ArrayUtils.subarray(array, 
8733, 4), "start overshoot, any end, object test");
         // array type tests
@@ -5781,6 +5786,7 @@ void testSubarrayLong() {
                 "empty array, object test");
 
         assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
 
         assertSame(ArrayUtils.EMPTY_LONG_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
 
@@ -5808,6 +5814,7 @@ void testSubarrayObject() {
         assertNull(ArrayUtils.subarray(nullArray, 0, 3), "null input");
         assertEquals("", 
StringUtils.join(ArrayUtils.subarray(ArrayUtils.EMPTY_OBJECT_ARRAY, 1, 2)), 
"empty array");
         assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 4, 
2)), "start > end");
+        assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 
2147483647, -2147483648)), "start > end");
         assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 3, 
3)), "start == end");
         assertEquals("abcd", StringUtils.join(ArrayUtils.subarray(objectArray, 
-2, 4)), "start undershoot, normal end");
         assertEquals("", StringUtils.join(ArrayUtils.subarray(objectArray, 33, 
4)), "start overshoot, any end");
@@ -5860,6 +5867,7 @@ void testSubarrayShort() {
         assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_SHORT_ARRAY, 1, 2),
                 "empty array, object test");
         assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_SHORT_ARRAY, ArrayUtils.subarray(array, 
8733, 4),
                 "start overshoot, any end, object test");
@@ -5895,6 +5903,7 @@ void testSubarrChar() {
 
         assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, 
ArrayUtils.subarray(ArrayUtils.EMPTY_CHAR_ARRAY, 1, 2), "empty array, object 
test");
         assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 4, 
1), "start > end, object test");
+        assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 
2147483647, -2147483648), "start > end, possible overflow");
         assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 3, 
3), "start == end, object test");
         assertSame(ArrayUtils.EMPTY_CHAR_ARRAY, ArrayUtils.subarray(array, 
8733, 4), "start overshoot, any end, object test");
 

Reply via email to