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

garydgregory 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 680bceccd ArrayUtils.addAll/insert length arithmetic overflows 
(undeclared NegativeArraySizeException) while sibling concat is 
overflow-checked (f023).
680bceccd is described below

commit 680bceccdf337ec1094812720564c357ee83a559
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Sep 5 15:10:54 2026 -0400

    ArrayUtils.addAll/insert length arithmetic overflows (undeclared
    NegativeArraySizeException) while sibling concat is overflow-checked
    (f023).
---
 src/changes/changes.xml                            |  1 +
 .../java/org/apache/commons/lang3/ArrayUtils.java  | 55 ++++++++++++++--------
 2 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 9c23421e4..d6c2f9a74 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -272,6 +272,7 @@ java.lang.NullPointerException: Cannot invoke
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">ClassUtils.getClass() name normalization (whitespace stripping + 
dot-to-dollar rewriting) defeats host-side class-name string checks 
(f020).</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Fraction.getFraction(String) throws undeclared ArithmeticException on 
crafted numeric strings ('9999999999.5', '1/0', mixed-number overflow) 
(f021).</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">StringEscapeUtils.escapeHtml4/3 apostrophe gap: single-quoted and 
unquoted HTML attribute contexts are trivially breakable, and the javadoc 
discloses the gap only as an HTML4 entity-legality footnote (f022).</action>
+    <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">ArrayUtils.addAll/insert length arithmetic overflows (undeclared 
NegativeArraySizeException) while sibling concat is overflow-checked 
(f023).</action>
     <!-- ADD -->
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add JavaVersion.JAVA_27.</action>
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add SystemUtils.IS_JAVA_27.</action>
diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java 
b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
index 18b586655..021e6d2d3 100644
--- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
@@ -869,6 +869,7 @@ public static <T> T[] add(final T[] array, final T element) 
{
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new boolean[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static boolean[] addAll(final boolean[] array1, final boolean... 
array2) {
@@ -878,7 +879,7 @@ public static boolean[] addAll(final boolean[] array1, 
final boolean... array2)
         if (array2 == null) {
             return clone(array1);
         }
-        final boolean[] joinedArray = new boolean[array1.length + 
array2.length];
+        final boolean[] joinedArray = new boolean[addExact(array1.length, 
array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -901,6 +902,7 @@ public static boolean[] addAll(final boolean[] array1, 
final boolean... array2)
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new byte[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static byte[] addAll(final byte[] array1, final byte... array2) {
@@ -910,7 +912,7 @@ public static byte[] addAll(final byte[] array1, final 
byte... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final byte[] joinedArray = new byte[array1.length + array2.length];
+        final byte[] joinedArray = new byte[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -933,6 +935,7 @@ public static byte[] addAll(final byte[] array1, final 
byte... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new char[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static char[] addAll(final char[] array1, final char... array2) {
@@ -942,7 +945,7 @@ public static char[] addAll(final char[] array1, final 
char... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final char[] joinedArray = new char[array1.length + array2.length];
+        final char[] joinedArray = new char[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -965,6 +968,7 @@ public static char[] addAll(final char[] array1, final 
char... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new double[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static double[] addAll(final double[] array1, final double... 
array2) {
@@ -974,7 +978,7 @@ public static double[] addAll(final double[] array1, final 
double... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final double[] joinedArray = new double[array1.length + array2.length];
+        final double[] joinedArray = new double[addExact(array1.length, 
array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -997,6 +1001,7 @@ public static double[] addAll(final double[] array1, final 
double... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new float[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static float[] addAll(final float[] array1, final float... array2) {
@@ -1006,7 +1011,7 @@ public static float[] addAll(final float[] array1, final 
float... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final float[] joinedArray = new float[array1.length + array2.length];
+        final float[] joinedArray = new float[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -1029,6 +1034,7 @@ public static float[] addAll(final float[] array1, final 
float... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new int[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static int[] addAll(final int[] array1, final int... array2) {
@@ -1038,7 +1044,7 @@ public static int[] addAll(final int[] array1, final 
int... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final int[] joinedArray = new int[array1.length + array2.length];
+        final int[] joinedArray = new int[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -1061,6 +1067,7 @@ public static int[] addAll(final int[] array1, final 
int... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new long[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static long[] addAll(final long[] array1, final long... array2) {
@@ -1070,7 +1077,7 @@ public static long[] addAll(final long[] array1, final 
long... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final long[] joinedArray = new long[array1.length + array2.length];
+        final long[] joinedArray = new long[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -1093,6 +1100,7 @@ public static long[] addAll(final long[] array1, final 
long... array2) {
      * @param array1  The first array whose elements are added to the new 
array.
      * @param array2  The second array whose elements are added to the new 
array.
      * @return The new short[] array or {@code null}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static short[] addAll(final short[] array1, final short... array2) {
@@ -1102,7 +1110,7 @@ public static short[] addAll(final short[] array1, final 
short... array2) {
         if (array2 == null) {
             return clone(array1);
         }
-        final short[] joinedArray = new short[array1.length + array2.length];
+        final short[] joinedArray = new short[addExact(array1.length, array2)];
         System.arraycopy(array1, 0, joinedArray, 0, array1.length);
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
         return joinedArray;
@@ -1131,7 +1139,7 @@ public static short[] addAll(final short[] array1, final 
short... array2) {
      * @return The new array, {@code null} if both arrays are {@code null}.
      *      The type of the new array is the type of the first array,
      *      unless the first array is null, in which case the type is the same 
as the second array.
-     * @throws IllegalArgumentException if the array types are incompatible.
+     * @throws IllegalArgumentException if the array types are incompatible or 
if the total array length exceeds {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 2.1
      */
     public static <T> T[] addAll(final T[] array1, 
@SuppressWarnings("unchecked") final T... array2) {
@@ -1142,7 +1150,7 @@ public static <T> T[] addAll(final T[] array1, 
@SuppressWarnings("unchecked") fi
             return clone(array1);
         }
         final Class<T> type1 = getComponentType(array1);
-        final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> 
newInstance(type1, array1.length + array2.length));
+        final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> 
newInstance(type1, addExact(array1.length, array2)));
         try {
             System.arraycopy(array2, 0, joinedArray, array1.length, 
array2.length);
         } catch (final ArrayStoreException ase) {
@@ -3125,6 +3133,7 @@ private static int indexOfNaN(final double[] array, final 
int startIndex) {
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static boolean[] insert(final int index, final boolean[] array, 
final boolean... values) {
@@ -3137,7 +3146,7 @@ public static boolean[] insert(final int index, final 
boolean[] array, final boo
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final boolean[] result = new boolean[array.length + values.length];
+        final boolean[] result = new boolean[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3166,6 +3175,7 @@ public static boolean[] insert(final int index, final 
boolean[] array, final boo
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static byte[] insert(final int index, final byte[] array, final 
byte... values) {
@@ -3178,7 +3188,7 @@ public static byte[] insert(final int index, final byte[] 
array, final byte... v
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final byte[] result = new byte[array.length + values.length];
+        final byte[] result = new byte[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3207,6 +3217,7 @@ public static byte[] insert(final int index, final byte[] 
array, final byte... v
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static char[] insert(final int index, final char[] array, final 
char... values) {
@@ -3219,7 +3230,7 @@ public static char[] insert(final int index, final char[] 
array, final char... v
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final char[] result = new char[array.length + values.length];
+        final char[] result = new char[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3248,6 +3259,7 @@ public static char[] insert(final int index, final char[] 
array, final char... v
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static double[] insert(final int index, final double[] array, final 
double... values) {
@@ -3260,7 +3272,7 @@ public static double[] insert(final int index, final 
double[] array, final doubl
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final double[] result = new double[array.length + values.length];
+        final double[] result = new double[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3289,6 +3301,7 @@ public static double[] insert(final int index, final 
double[] array, final doubl
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static float[] insert(final int index, final float[] array, final 
float... values) {
@@ -3301,7 +3314,7 @@ public static float[] insert(final int index, final 
float[] array, final float..
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final float[] result = new float[array.length + values.length];
+        final float[] result = new float[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3330,6 +3343,7 @@ public static float[] insert(final int index, final 
float[] array, final float..
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static int[] insert(final int index, final int[] array, final 
int... values) {
@@ -3342,7 +3356,7 @@ public static int[] insert(final int index, final int[] 
array, final int... valu
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final int[] result = new int[array.length + values.length];
+        final int[] result = new int[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3371,6 +3385,7 @@ public static int[] insert(final int index, final int[] 
array, final int... valu
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static long[] insert(final int index, final long[] array, final 
long... values) {
@@ -3383,7 +3398,7 @@ public static long[] insert(final int index, final long[] 
array, final long... v
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final long[] result = new long[array.length + values.length];
+        final long[] result = new long[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3412,6 +3427,7 @@ public static long[] insert(final int index, final long[] 
array, final long... v
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     public static short[] insert(final int index, final short[] array, final 
short... values) {
@@ -3424,7 +3440,7 @@ public static short[] insert(final int index, final 
short[] array, final short..
         if (index < 0 || index > array.length) {
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
-        final short[] result = new short[array.length + values.length];
+        final short[] result = new short[addExact(array.length, values)];
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {
             System.arraycopy(array, 0, result, 0, index);
@@ -3454,6 +3470,7 @@ public static short[] insert(final int index, final 
short[] array, final short..
      * @param values The new values to insert, may be {@code null}.
      * @return The new array or {@code null} if the given array is {@code 
null}.
      * @throws IndexOutOfBoundsException if {@code array} is provided and 
either {@code index < 0} or {@code index > array.length}.
+     * @throws IllegalArgumentException if the total array length exceeds 
{@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
      * @since 3.6
      */
     @SafeVarargs
@@ -3475,7 +3492,7 @@ public static <T> T[] insert(final int index, final T[] 
array, final T... values
             throw new IndexOutOfBoundsException("Index: " + index + ", Length: 
" + array.length);
         }
         final Class<T> type = getComponentType(array);
-        final int length = array.length + values.length;
+        final int length = addExact(array.length, values);
         final T[] result = newInstance(type, length);
         System.arraycopy(values, 0, result, index, values.length);
         if (index > 0) {

Reply via email to