From 5de7a0df15e208c9306bf7c6b23a56f2878704c8 Mon Sep 17 00:00:00 2001 From: dev_agent Date: Sat, 3 Oct 2026 08:52:14 -0400 Subject: [PATCH] Reject the zero instant in Timestamp.Scan Scan accepted "0001-01-01T00:00:00.000Z" and produced a zero Timestamp that Value then refused to write. Reject it on read, consistent with Value. Co-Authored-By: Claude Opus 5.5 --- internal/store/time.go | 6 +++++- internal/store/time_test.go | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/store/time.go b/internal/store/time.go index cb05120..e558bc2 100644 --- a/internal/store/time.go +++ b/internal/store/time.go @@ -41,7 +41,8 @@ func (t Timestamp) Value() (driver.Value, error) { return t.String(), nil } -// Scan implements sql.Scanner. It accepts only TEXT in the stored form. +// Scan implements sql.Scanner. It accepts only TEXT in the stored form, and +// rejects the zero instant, which Value refuses to write. func (t *Timestamp) Scan(src any) error { s, ok := src.(string) if !ok { @@ -54,6 +55,9 @@ func (t *Timestamp) Scan(src any) error { if parsed.Format(timestampLayout) != s { return fmt.Errorf("store: scan Timestamp %q: want %s", s, timestampLayout) } + if parsed.IsZero() { + return fmt.Errorf("store: scan Timestamp %q: zero Timestamp", s) + } t.Time = parsed return nil } diff --git a/internal/store/time_test.go b/internal/store/time_test.go index 0af3a45..e809633 100644 --- a/internal/store/time_test.go +++ b/internal/store/time_test.go @@ -72,6 +72,7 @@ func TestTimestampRejects(t *testing.T) { for _, src := range []any{ nil, int64(0), []byte("2026-10-03T12:37:05.123Z"), "2026-10-03T12:37:05Z", "2026-10-03T08:37:05.123-04:00", "2026-10-03T12:37:05,123Z", "garbage", + "0001-01-01T00:00:00.000Z", } { var ts Timestamp if err := ts.Scan(src); err == nil {