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-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new db57942a Reject an empty option name in getMatchingOptions (#434)
db57942a is described below

commit db57942a6a593ebf2be28172a22a2f1db6bdccb9
Author: farkhalit rida <[email protected]>
AuthorDate: Sat Aug 1 23:40:24 2026 +0530

    Reject an empty option name in getMatchingOptions (#434)
    
    * reject an empty option name in getMatchingOptions
    
    An empty name after hyphen stripping matched every long option, so the 
token "--=value" bound the value to a long option that was never named.
    
    * Document and test null-tolerant getMatchingOptions
    
    Signed-off-by: farkhalit rida <[email protected]>
    
    * Update Javadoc for getMatchingOptions method
    
    ---------
    
    Signed-off-by: farkhalit rida <[email protected]>
    Co-authored-by: Gary Gregory <[email protected]>
---
 src/main/java/org/apache/commons/cli/Options.java     |  8 ++++++--
 src/test/java/org/apache/commons/cli/OptionsTest.java | 14 ++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/commons/cli/Options.java 
b/src/main/java/org/apache/commons/cli/Options.java
index 40d8b110..dcb6b52b 100644
--- a/src/main/java/org/apache/commons/cli/Options.java
+++ b/src/main/java/org/apache/commons/cli/Options.java
@@ -212,13 +212,17 @@ public class Options implements Serializable {
     /**
      * Gets the options with a long name starting with the name specified.
      *
-     * @param opt The partial name of the option.
-     * @return The options matching the partial name specified, or an empty 
list if none matches.
+     * @param opt The partial name of the option, may be {@code null}.
+     * @return The options matching the partial name specified, or an empty 
list if none matches or the name is null or empty.
      * @since 1.3
      */
     public List<String> getMatchingOptions(final String opt) {
         final String clean = Util.stripLeadingHyphens(opt);
         final List<String> matchingOpts = new ArrayList<>();
+        // a null or empty name is not a partial name; empty would match every 
long option
+        if (Util.isEmpty(clean)) {
+            return matchingOpts;
+        }
         // for a perfect match return the single option only
         if (longOpts.containsKey(clean)) {
             return Collections.singletonList(clean);
diff --git a/src/test/java/org/apache/commons/cli/OptionsTest.java 
b/src/test/java/org/apache/commons/cli/OptionsTest.java
index f0ac9525..d6b2f466 100644
--- a/src/test/java/org/apache/commons/cli/OptionsTest.java
+++ b/src/test/java/org/apache/commons/cli/OptionsTest.java
@@ -182,6 +182,20 @@ class OptionsTest {
         assertToStrings(options.getOption("verbose"));
     }
 
+    @Test
+    void testGetMatchingOptsEmptyName() throws Exception {
+        final Options options = new Options();
+        
options.addOption(Option.builder("c").longOpt("config-file").hasArg().get());
+        assertTrue(options.getMatchingOptions(null).isEmpty());
+        assertTrue(options.getMatchingOptions("").isEmpty());
+        assertTrue(options.getMatchingOptions("-").isEmpty());
+        assertTrue(options.getMatchingOptions("--").isEmpty());
+        // "--=value" names no option, so it must not bind a value to 
config-file
+        for (final CommandLineParser parser : new CommandLineParser[] { new 
DefaultParser(), new PosixParser() }) {
+            assertThrows(UnrecognizedOptionException.class, () -> 
parser.parse(options, new String[] { "--=/etc/shadow" }));
+        }
+    }
+
     @Test
     void testGetOptionsGroups() {
         final Options options = new Options();

Reply via email to