Skip to content

sql(mysql): tighten text date validation + binary zero-date NaN

597d25f
Select commit
Loading
Failed to load commit list.
Open

sql(mysql): decode DATETIME/TIMESTAMP as UTC #29216

sql(mysql): tighten text date validation + binary zero-date NaN
597d25f
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Apr 12, 2026 in 22m 15s

Code review found 1 important issue

Found 3 candidates, confirmed 2. See review comments for details.

Details

Severity Count
🔴 Important 1
🟡 Nit 0
🟣 Pre-existing 1
Severity File:Line Issue
🔴 Important src/sql/mysql/protocol/DecodeBinaryValue.zig:134-135 Partial zero-dates in binary protocol normalize instead of NaN
🟣 Pre-existing src/sql/mysql/MySQLTypes.zig:663-673 gregorianDate() panics on pre-1970 dates (write path)

Annotations

Check failure on line 135 in src/sql/mysql/protocol/DecodeBinaryValue.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

Partial zero-dates in binary protocol normalize instead of NaN

The binary protocol path for partial zero-dates like '2024-00-15' (month=0) or '2024-01-00' (day=0) silently normalizes them to wrong timestamps instead of NaN. MySQL sends these as non-zero-length 4/7/11-byte payloads, bypassing the zero-length NaN guard added by this PR; fromBinary() reads month/day with no range validation, so toJSTimestamp() calls gregorianDateTimeToMSUTC(year, 0, day) which triggers setMonth(-1) in WTF::GregorianDateTime and normalizes to December of year-1. Meanwhile fromT

Check notice on line 673 in src/sql/mysql/MySQLTypes.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

gregorianDate() panics on pre-1970 dates (write path)

Pre-existing bug: `gregorianDate()` only iterates forward from 1970, so any negative `days` value (representing a pre-1970 date) skips both while-loops entirely and attempts `@intCast(d + 1)` to `u8` where `d` is still the original large negative number — a panic in Zig Debug/ReleaseSafe mode and silent garbage in ReleaseFast. Any INSERT of a pre-1970 JS Date (e.g. `new Date('1900-01-01')`) via Bun MySQL will trigger this through the `fromJS() → fromUnixTimestamp() → gregorianDate()` call chain.