Skip to content

fix: reject offset on a bare local time or date - #59

Open
hong4rc wants to merge 1 commit into
squirrelchat:mistressfrom
hong4rc:fix/reject-offset-on-local-time-date
Open

fix: reject offset on a bare local time or date#59
hong4rc wants to merge 1 commit into
squirrelchat:mistressfrom
hong4rc:fix/reject-offset-on-local-time-date

Conversation

@hong4rc

@hong4rc hong4rc commented Jun 29, 2026

Copy link
Copy Markdown

Issue

parse() accepts a TOML time-of-day or date that carries a timezone offset (Z or ±HH:MM) and silently corrupts the value instead of rejecting it. Per TOML, an offset is only valid on an offset-date-time (a full date and time); local-time, local-date, and local-date-time have no offset.

opens = 08:30:00-07:00   # accepted, parsed as 15:30 (shifted to UTC) — not rejected
t     = 07:32:00Z        # accepted, Z silently dropped → 07:32 local
d     = 1979-05-27Z      # accepted, Z silently dropped
Input Current Expected (TOML 1.0)
08:30:00-07:00 accepted → 15:30:00 (corrupted) error — offset not allowed on a local time
07:32:00Z accepted → 07:32:00 (Z dropped) error
1979-05-27Z accepted → 1979-05-27 (Z dropped) error
1979-05-27T07:32:00-07:00 accepted (correct) valid offset-date-time
07:32:00 / 1979-05-27 accepted (correct) valid local-time / local-date

Why it happens

In TomlDate's constructor (src/date.ts), the offset capture group (match[3]) is applied whenever it's present, with no check that a date (match[1]) and a time (match[2]) accompany it. super(...) then builds a valid Date shifted to UTC, but the value is classified as a local time/date, so reading it back yields the UTC-shifted instant — a silently wrong value, and an invalid construct accepted.

Fix

Reject an offset that isn't on a full date-time — match[3] present while match[1] (date) or match[2] (time) is missing — alongside the existing rollover-hours guard. Offset-date-times and bare local-time/local-date are unaffected.

Tests

Added 07:32:00Z, 07:32:00-07:00, and 1979-05-27Z to the "rejects invalid dates" suite. Full suite passes (141 tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant