[common] Range-check the digit guard in DateTimeUtils - #9649
Open
LuciferYang wants to merge 1 commit into
Open
Conversation
parseDate and parseTime return null for unparseable input and guard every Integer.parseInt with isInteger, which only checked that the characters were digits. An eleven-digit component passed it and parseInt threw NumberFormatException out of a method whose other failure paths return null. Check the range in the guard, in front of all eleven parseInt calls.
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.
Purpose
close #9648
DateTimeUtils.parseDateandparseTimereturn null for input they cannot parse, and they guard everyInteger.parseIntwithisInteger. That guard only checked the characters:A component of eleven digits therefore passed it and
Integer.parseIntthrewNumberFormatException, escaping a method whose every other failure path returns null.parseDate("2147483648-01-01")andparseTime("2147483648:00:00")both do it.The guard now also checks the range, which is enough because it sits in front of each of the eleven
parseIntcalls in those two methods. Nothing else changes: no signature, no local variable type, no arithmetic.Callers see the difference as an exception type. Through the casts,
NumberFormatExceptionbecomes theDateTimeExceptionthatBinaryStringUtils.toDateraises for any unparseable string, which is what a caller already gets for"99999-01-01"(rejected byisIllegalDate) or"not-a-date". The HivePaimonTimeObjectInspector.convertpasses theIntegerthrough, so a TIME column holding such a value writes NULL rather than failing, matching what it already does for other invalid times.Tests
DateTimeUtilsTest.testParseDateAndTimeOverflowReturnsNullcovers a too-large year, month, day and hour, and the two boundary cases:2147483648is the smallest ten-digit value that does not fit anint, and2147483647does fit but is still not a valid year, so both have to come back null through different branches. Valid values are asserted alongside them.Against the unfixed guard the test errors with
NumberFormatException: For input string: "2147483648".mvn -pl paimon-common -Dtest=DateTimeUtilsTest teston JDK 8: 12 tests, 0 failures.spotless:checkandcheckstyle:checkon paimon-common are clean.