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 7d77ecce Reject trailing text after the date in Converter.DATE (#435)
7d77ecce is described below

commit 7d77ecce8b11763b7282d6b40dffdb4ce8e85668
Author: farkhalit rida <[email protected]>
AuthorDate: Sat Aug 1 23:56:36 2026 +0530

    Reject trailing text after the date in Converter.DATE (#435)
    
    * reject trailing text after the date in Converter.DATE
    
    * Only fall back to English locale when the date fails to parse
    
    Restrict the English retry to when the default-locale parse matches nothing;
    a partial match is a trailing-text failure and now throws with the parse
    position instead of retrying and reporting a misleading offset.
---
 .../java/org/apache/commons/cli/Converter.java     | 22 +++++++++++++++++-----
 .../org/apache/commons/cli/ConverterTests.java     | 18 ++++++++++++++++++
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/commons/cli/Converter.java 
b/src/main/java/org/apache/commons/cli/Converter.java
index fcb9c43b..1faf7817 100644
--- a/src/main/java/org/apache/commons/cli/Converter.java
+++ b/src/main/java/org/apache/commons/cli/Converter.java
@@ -22,6 +22,7 @@ import java.net.URL;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
@@ -82,15 +83,26 @@ public interface Converter<T, E extends Exception> {
         final SimpleDateFormat format = new SimpleDateFormat(pattern);
         // reject out-of-range fields (for example "Feb 30") instead of 
silently rolling them over.
         format.setLenient(false);
-        try {
-            return format.parse(s);
-        } catch (final java.text.ParseException e) {
+        // SimpleDateFormat.parse(String) stops at the first character it 
cannot use and ignores any
+        // trailing text, so "<valid date> garbage" would be accepted. Parse 
from an explicit position
+        // and reject the value unless the whole string is consumed.
+        final ParsePosition pos = new ParsePosition(0);
+        Date date = format.parse(s, pos);
+        if (date == null) {
             // Date.toString() always emits English month/day names, so fall 
back to Locale.ENGLISH
-            // when the default locale rejects the documented format.
+            // when the default locale rejects the documented format. Only 
retry when the default
+            // locale matched nothing; a partial match is a trailing-text 
failure, handled below.
             final SimpleDateFormat englishFormat = new 
SimpleDateFormat(pattern, Locale.ENGLISH);
             englishFormat.setLenient(false);
-            return englishFormat.parse(s);
+            pos.setIndex(0);
+            pos.setErrorIndex(-1);
+            date = englishFormat.parse(s, pos);
         }
+        if (date == null || pos.getIndex() != s.length()) {
+            final int errorIndex = pos.getErrorIndex() >= 0 ? 
pos.getErrorIndex() : pos.getIndex();
+            throw new java.text.ParseException(String.format("Unparseable 
date: \"%s\"", s), errorIndex);
+        }
+        return date;
     };
 
     /**
diff --git a/src/test/java/org/apache/commons/cli/ConverterTests.java 
b/src/test/java/org/apache/commons/cli/ConverterTests.java
index 1f5efad5..64052c41 100644
--- a/src/test/java/org/apache/commons/cli/ConverterTests.java
+++ b/src/test/java/org/apache/commons/cli/ConverterTests.java
@@ -86,6 +86,24 @@ public class ConverterTests {
         assertThrows(java.text.ParseException.class, () -> 
Converter.DATE.apply("Jun 06 17:48:57 EDT 2002"));
     }
 
+    @Test
+    void testDateRejectsTrailingText() throws Exception {
+        final Date expected = new Date(1023400137000L);
+        final String formatted = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz 
yyyy").format(expected);
+        assertThrows(java.text.ParseException.class, () -> 
Converter.DATE.apply(formatted + " trailing"));
+    }
+
+    @Test
+    @DefaultLocale(language = "de", country = "DE")
+    void testDateRejectsTrailingTextLocaleDe() throws Exception {
+        // Trailing text must be rejected even when a non-English default 
locale parses the date, and
+        // the reported error position should point past the parsed date 
rather than at index 0.
+        final Date expected = new Date(1023400137000L);
+        final String formatted = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz 
yyyy").format(expected);
+        final java.text.ParseException e = 
assertThrows(java.text.ParseException.class, () -> 
Converter.DATE.apply(formatted + " trailing"));
+        assertEquals(formatted.length(), e.getErrorOffset());
+    }
+
     @Test
     @DefaultLocale(language = "de", country = "DE")
     void testDateLocaleDe() throws Exception {

Reply via email to