Ruiqi Dong created CLI-344:
------------------------------

             Summary: Option.processValue() throws NullPointerException when 
passed null value with value separator configured
                 Key: CLI-344
                 URL: https://issues.apache.org/jira/browse/CLI-344
             Project: Commons CLI
          Issue Type: Bug
    Affects Versions: 1.10.0
            Reporter: Ruiqi Dong
             Fix For: 1.10.0
         Attachments: Option.java, OptionTest.java

The {{Option.processValue(String value)}} method does not properly handle null 
input values. When a null value is passed to this method and the Option has a 
value separator configured, it throws a {{NullPointerException}} instead of 
handling the null gracefully with proper validation.

 

*Steps to Reproduce:*

Option option = new Option("D", true, "Define property");
option.setValueSeparator('=');
option.processValue(null);  // Throws NullPointerException

 

*Expected Behavior:* The method should validate the input and throw an 
{{IllegalArgumentException}} with a clear error message when null is passed, 
consistent with how other methods in the library handle invalid input.

*Actual Behavior:* A {{NullPointerException}} is thrown at line 839 in 
Option.java when the code attempts to call {{indexOf()}} on the null value:

java.lang.NullPointerException
    at org.apache.commons.cli.Option.processValue(Option.java:839)

 

*Root Cause Analysis:*

The {{processValue()}} method assigns the input value directly to a local 
variable without null checking:

void processValue(final String value) {
    if (argCount == UNINITIALIZED) {
        throw new IllegalArgumentException("NO_ARGS_ALLOWED");
    }
    String add = value;  // No null check
    if (hasValueSeparator()) {
        final char sep = getValueSeparator();
        int index = add.indexOf(sep);  // NPE occurs here when add is null
        // ...
    }
}

 

*Unit Test Cases:*

@Test
public void testProcessValueWithNullThrowsIllegalArgumentException() {
    Option option = new Option("D", true, "Define property");
    option.setValueSeparator('=');
    
    IllegalArgumentException exception = assertThrows(
        IllegalArgumentException.class, 
        () -> option.processValue(null),
        "processValue(null) should throw IllegalArgumentException"
    );
    
    assertTrue(exception.getMessage().contains("null"),
        "Exception message should indicate null value issue");
}

 

*Test Results:*

[*INFO*] Running org.apache.commons.cli.{*}OptionTest{*}{*}{*}

[*ERROR*] *Tests* {*}run: 1{*}, *Failures: 1*, Errors: 0, Skipped: 0, Time 
elapsed: 0.001 s *<<< FAILURE!* -- in 
org.apache.commons.cli.{*}OptionTest{*}{*}{*}

[*ERROR*] 
org.apache.commons.cli.OptionTest.testProcessValueWithNullThrowsIllegalArgumentException
 -- Time elapsed: 0.001 s <<< FAILURE!

org.opentest4j.AssertionFailedError: processValue(null) should throw 
IllegalArgumentException ==> Unexpected exception type thrown, expected: 
<java.lang.IllegalArgumentException> but was: <java.lang.NullPointerException>

 at 
org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)

 at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:67)

 at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:39)

 at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3153)

 at 
org.apache.commons.cli.OptionTest.testProcessValueWithNullThrowsIllegalArgumentException(OptionTest.java:32)

 at java.lang.reflect.Method.invoke(Method.java:498)

 at java.util.ArrayList.forEach(ArrayList.java:1259)

 at java.util.ArrayList.forEach(ArrayList.java:1259)

Caused by: java.lang.NullPointerException

 at org.apache.commons.cli.Option.processValue(Option.java:839)

 at 
org.apache.commons.cli.OptionTest.lambda$testProcessValueWithNullThrowsIllegalArgumentException$0(OptionTest.java:34)

 at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:53)

 ... 6 more

 

*Suggested Fix:* 

Add null validation at the beginning of the method:

void processValue(final String value) {
    if (value == null) {
        throw new IllegalArgumentException("The value must not be null");
    }
    if (argCount == UNINITIALIZED) {
        throw new IllegalArgumentException("NO_ARGS_ALLOWED");
    }
    // ... rest of the method remains unchanged
}



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

Reply via email to