Conversation
A time format ending with a single quote, such as "yyyy'", made convertFormat read formatRune[i+1] past the end of the slice and panic. Bounds-check the real-quote lookahead like the other cases; a trailing quote is then consumed as an unterminated text delimiter, consistent with the existing lenient handling of unterminated quotes mid-format. Signed-off-by: zjncs <18910855655@163.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4124 +/- ##
==========================================
+ Coverage 70.89% 70.93% +0.05%
==========================================
Files 471 471
Lines 55430 55430
==========================================
+ Hits 39292 39318 +26
+ Misses 13101 13084 -17
+ Partials 3037 3028 -9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ngjaying
left a comment
There was a problem hiding this comment.
Thanks for fixing the out-of-bounds panic. The bounds check itself looks correct, but I think the resulting behavior for unmatched quotes should be changed before merge.
convertFormat already returns an error, and both ParseTime and FormatTime propagate that error. Instead of silently accepting malformed formats such as yyyy' as 2006 or yyyy'abc as 2006abc, please return an error for an unterminated quote.
That would fix the panic while preserving invalid-format detection for callers.
Suggested test expectations:
yyyy'→ erroryyyy'abc→ error'day 'yyyy→day 2006yyyy''→2006'
Also, the PR description says this lenient behavior matches Java SimpleDateFormat semantics, but SimpleDateFormat treats an unterminated quote as an invalid pattern rather than silently consuming it.
Non-blocking: doubled quotes inside quoted text, for example 'o''clock', also appear worth checking separately, but that does not need to be part of this fix.
Description
A time format string ending with a single quote made
convertFormatpanic:convertFormatis the converter behindformat_time(now(), fmt)(the format argument is a user string literal) and the SQL sink's datetime format option, so a malformed format string currently crashes the rule instead of producing an error.Root cause
In the quote case of
pkg/cast/time.go, the real-quote lookahead readsformatRune[i+1]without checkingi+1 < lenFormat:Every other case in the function bounds-checks its lookahead (
i+j < lenFormat); only this one does not. When the quote is the last character of the format,i+1is out of range.Changes
i+1 < lenFormatbound check. A trailing single quote now falls through to the text-delimiter branch and is consumed as an unterminated delimiter — the same lenient behavior the function already applies to unterminated quotes in the middle of a format (e.g."yyyy'abc"→"2006abc", matching JavaSimpleDateFormatsemantics this converter mimics).TestConvertFormatwith quote cases: trailing quote (no panic, consumed), quoted text'day 'yyyy, escaped quoteyyyy'', and unterminated mid-format quote.How has this been tested?
Fail-before / pass-after (master @ 7a27fb5):
Full package after the fix:
go vet ./pkg/cast/andgo fmtclean.Behavior change
None for valid formats. A format ending in a single quote changes from panic to being treated like any other unterminated quote (consumed), instead of crashing the calling rule.
AI assistance disclosure
This change was prepared with the assistance of an AI coding agent; the bug, reproduction, fix, and test were all verified locally by me as described above.