[ 
https://issues.apache.org/jira/browse/CAMEL-25151?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25151.
---------------------------------
    Fix Version/s: 4.23.0
       Resolution: Fixed

The fix is merged on main, so it is in Camel 4.23.0:
* aeaf7d9db100 CAMEL-25151: camel-bindy - a java.util.Date value longer than 
its pattern is parsed

Resolving, as the ticket was not updated when the PR was merged.

_Claude Code on behalf of Claus Ibsen_

> camel-bindy - a java.util.Date field rejects a valid value that is longer 
> than its pattern (M/d/yyyy with 12/25/2026, h:mm a, MMMM), so Bindy cannot 
> read back dates it has written
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25151
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25151
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-bindy
>            Reporter: shashank
>            Priority: Minor
>             Fix For: 4.23.0
>
>
> {{DateFormatFactory.DatePatternFormat.parse}} (used for every 
> {{java.util.Date}} field of a CSV, fixed-length or key-value pair model) 
> refuses a value that has more characters than the pattern:
> {code:java}
> if (string.length() <= this.pattern.length()) {
>     df.setLenient(false);
>     return df.parse(string);
> } else {
>     throw new FormatException("Date provided does not fit the pattern 
> defined");
> }
> {code}
> A pattern letter count is a minimum width, not a maximum: {{M}}, {{d}}, {{H}} 
> and {{h}} print two digits for values of 10 and more, {{MMMM}} and {{EEEE}} 
> print full names, {{a}} prints {{AM}}/{{PM}} for one letter. So valid dates 
> in the pattern's own format are rejected:
> ||pattern||value||result||
> |{{M/d/yyyy}}|{{12/25/2026}}|FormatException (10 characters for an 8 
> character pattern)|
> |{{d.M.yyyy}}|{{25.12.2026}}|FormatException|
> |{{MMMM d yyyy}}|{{September 30 2026}}|FormatException|
> |{{h:mm a}}|{{11:45 PM}}, also {{9:05 AM}}|FormatException for every value|
> |{{dd-MM-yyyy}}|{{25-12-2026}}|ok (the width is fixed)|
> This also breaks the round trip: marshal writes {{12/25/2026}} for the 
> pattern {{M/d/yyyy}}, and unmarshal of that text fails with "Date provided 
> does not fit the pattern defined". For {{M/d/yyyy}} about four dates out of 
> five fail (every day from the 10th and every date in October to December).
> The check was added to reject a date followed by other characters, such as 
> {{20090901-10:32:30}} for {{yyyyMMdd}}, because {{DateFormat.parse(String)}} 
> stops at the end of the pattern and ignores the rest. CAMEL-11620 removed the 
> same check from the {{LocalDate}}, {{LocalDateTime}} and {{LocalTime}} 
> factories, but not from the {{java.util.Date}} one.
> h3. Reproduction
> {code:java}
> @CsvRecord(separator = ";")
> public static class Row {
>     @DataField(pos = 1, pattern = "M/d/yyyy")
>     private Date us;
> }
> // unmarshal of "12/25/2026" -> IllegalArgumentException: Date provided does 
> not fit the pattern defined, position: 1, line: 1
> // marshal of 2026-11-30 gives "11/30/2026", and unmarshal of that text fails 
> the same way
> {code}
> A unit test with the four patterns above fails on main. A small formal model 
> (Lean 4) of the check shows that it accepts the output of {{format}} exactly 
> when every numeric field has no more digits than its pattern letters, and 
> that the fix below accepts every formatted date and still rejects a date 
> followed by other characters.
> h3. Affected versions
> The check is the same in 2.25.0, 3.0.0, 4.0.0, 4.14.0, 4.18.0, 4.22.0 and 
> main.
> h3. Proposed fix
> Keep the check for what it was meant to catch: when the value is longer than 
> the pattern, parse it with a {{ParsePosition}} and accept it only when the 
> whole value was used; otherwise throw the same {{FormatException}} as before:
> {code:java}
> } else {
>     df.setLenient(false);
>     ParsePosition position = new ParsePosition(0);
>     date = df.parse(string, position);
>     if (date == null || position.getIndex() != string.length()) {
>         throw new FormatException("Date provided does not fit the pattern 
> defined");
>     }
>     return date;
> }
> {code}
> A value that is not longer than the pattern takes exactly the same path as 
> today, so nothing that is accepted today changes. (Requiring the whole value 
> to be used for every value would be stricter than today: for example 
> {{2026-09-30T10:11:12Z}} with the pattern {{yyyy-MM-dd'T'HH:mm:ss}}, 20 
> characters for a 21 character pattern because of the quotes, is accepted 
> today with the {{Z}} ignored, and would be rejected.) A date followed by 
> other characters is still rejected with the same {{FormatException}} and 
> message (the existing tests 
> {{BindySimpleCsvUnmarshallTest.testMessageWithErroneousDate}} and 
> {{BindySimpleCsvUnmarshallPositionModifiedTest}} pass unchanged).
> Duplicate check (2026-09-30): JIRA "bindy" with "date" and "pattern", "does 
> not fit the pattern", "java.util.Date": only CAMEL-11620 (java.time, fixed) 
> and older unrelated issues. No open pull request touches the Bindy date 
> factories.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to