Reject trailing characters in strict date validation#425
Merged
garydgregory merged 1 commit intoJul 17, 2026
Conversation
Parse with a ParsePosition and require the whole value to be consumed when strict, so a value with trailing text such as "11/11/199f" no longer validates against "MM/dd/yyyy".
garydgregory
added a commit
that referenced
this pull request
Jul 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chasing how the
strictflag is meant to enforce an exact match in the pattern-based date helpers, I found it rests entirely ondatePattern.length() != value.length().SimpleDateFormat.parse(String)stops at the first character it cannot read instead of failing, so a value whose trailing rubbish keeps the length equal to the pattern walks straight through:formatDate("11/11/199f", "MM/dd/yyyy", true)consumes only11/11/199, quietly reads the year as 199 and hands back aDate, andGenericValidator.isDatecalls the same string valid. The truncated year in a debug trace is what gives it away. The same heuristic sits inGenericTypeValidator.formatDateand in the deprecatedDateValidator.isValidthatGenericValidator.isDatedelegates to, so both accept the garbage.Both methods now run the parse through a
ParsePositionand, whenstrict, reject the value unless the parse reached the end of it, which is the full-consumption checkroutines/AbstractFormatValidator.parsealready uses. The length comparison stays in place, so an abbreviated field like2/12/1999is still rejected and non-strict parsing keeps its current leniency. Left alone, any caller trusting the strict contract to screen malformed dates takes attacker-supplied trailing data and stores a different date from the one submitted.mvn; that'smvnon the command line by itself.