You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary D. Gregory (Jira)" <ji...@apache.org> on 2025/07/29 14:40:00 UTC
[jira] [Updated] (CLI-344) Option.processValue() throws NullPointerException when passed null value with value separator configured
[ https://issues.apache.org/jira/browse/CLI-344?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Gary D. Gregory updated CLI-344:
--------------------------------
Priority: Minor (was: Major)
> 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
> Components: Options definition
> Affects Versions: 1.10.0
> Reporter: Ruiqi Dong
> Assignee: Gary D. Gregory
> Priority: Minor
> Fix For: 1.10.0
>
> Attachments: Option.java, OptionTest.java
>
> Original Estimate: 0.5h
> Remaining Estimate: 0.5h
>
> 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)