Partha Paul created LANG-1819:
---------------------------------

             Summary: ArrayUtils.removeAll() Does Not Throw 
IndexOutOfBoundsException for Null Array Input
                 Key: LANG-1819
                 URL: https://issues.apache.org/jira/browse/LANG-1819
             Project: Commons Lang
          Issue Type: Bug
          Components: lang.*
    Affects Versions: 3.20.0
         Environment: * Commons Lang version: (3.20.0 including the current 
snapshot version)
 * Java version: (javac 17.0.12)
            Reporter: Partha Paul


The Javadoc for all ArrayUtils.removeAll() overloads states that 
{color:#172b4d}{_}passing a null array should throw an 
IndexOutOfBoundsException{_}.{color} However, the actual implementation 
silently returns null instead, which violates the documented contract.
h2. Affected Method(s)

All primitive and Object overloads of removeAll(), including but not limited to:
 * removeAll(boolean[] array, int... indices)
 * removeAll(byte[] array, int... indices)
 * removeAll(char[] array, int... indices)
 * removeAll(double[] array, int... indices)
 * removeAll(float[] array, int... indices)
 * removeAll(int[] array, int... indices)
 * removeAll(long[] array, int... indices)
 * removeAll(short[] array, int... indices)
 * removeAll(T[] array, int... indices)

h2. Root Cause

All typed overloads delegate to the generic removeAll(Object array, int... 
indices) overload via a cast:
{code:java}
return (boolean[]) removeAll((Object) array, indices);
{code}
When array is null, casting it to Object preserves the null, and the generic 
overload returns null silently instead of throwing IndexOutOfBoundsException.
h2. Steps to Reproduce
{code:java}
@Test
void testRemoveAllThrowsIndexOutOfBoundException() {
    assertThrows(IndexOutOfBoundsException.class, () -> 
ArrayUtils.removeAll((boolean[]) null, 2));
}
{code}
h2. Expected Behavior

Per the Javadoc:
{quote}If the input array is null, an IndexOutOfBoundsException will be thrown, 
because in that case no valid index can be specified.
{quote}
An IndexOutOfBoundsException should be thrown.
h2. Actual Behavior

No exception is thrown. The method returns null.
h2. Proposed Fix

There are two valid approaches to resolving this inconsistency, and I am happy 
to submit a PR for whichever is preferred:
h3. Option A - Fix the implementation

Add an explicit null check in the generic removeAll(Object, int...) overload:
{code:java}
if (array == null) {
    throw new IndexOutOfBoundsException("Array is null, no valid index can be 
specified.");
}
{code}
This aligns the implementation with the documented contract, since returning 
null for a null array input is arguably surprising and may be an unsafe 
behavior.
h3. Option B - Update the documentation

Update the Javadoc across all overloads to reflect the actual behavior:
{code:java}
* If the input array is {@code null}, {@code null} will be returned.
{code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to