Skip to content

Commit a7bae68

Browse files
committed
Addresses cedar-policy/rfcs#94 concerns about time wrapping
The Go time package will silently ignore dates that don't exist on the calendar, instead carrying forward the erroneous time component. As an example, `2024-02-30` will become `2024-03-01`, since there was no February 30th, in 2024 (or ever). This change returns an error when there's a discrepancy between the numbers we parse from the string, and the component after creating a Go time.Time value from the parsed numbers.
1 parent d7b68aa commit a7bae68

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

types/datetime.go

+12
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ func ParseDatetime(s string) (Datetime, error) {
200200
t := time.Date(year, time.Month(month), day,
201201
hour, minute, second,
202202
int(time.Duration(milli)*time.Millisecond), time.UTC)
203+
204+
// Don't allow wrapping: https://github.com/cedar-policy/rfcs/pull/94
205+
tyear, tmonth, tday := t.Date()
206+
if year != tyear || time.Month(month) != tmonth || day != tday {
207+
return Datetime{}, fmt.Errorf("%w: date would wrap", errDatetime)
208+
}
209+
210+
thour, tminute, tsecond := t.Hour(), t.Minute(), t.Second()
211+
if hour != thour || minute != tminute || second != tsecond {
212+
return Datetime{}, fmt.Errorf("%w: time would wrap", errDatetime)
213+
}
214+
203215
t = t.Add(offset)
204216
return Datetime{value: t.UnixMilli()}, nil
205217
}

types/datetime_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ func TestDatetime(t *testing.T) {
100100
{"1995-01-01T00:00:00.000-0aaa", "error parsing datetime value: invalid time zone offset"},
101101
{"1995-01-01T00:00:00.000-aaaa", "error parsing datetime value: invalid time zone offset"},
102102
{"1995-01-01T00:00:00.000-aaaa0", "error parsing datetime value: unexpected trailer after time zone designator"},
103+
104+
// Prevent Wrapping invalid dates to real dates: See: cedar-policy/rfcs#94
105+
{"2024-02-30T00:00:00Z", "error parsing datetime value: date would wrap"},
106+
{"2024-02-29T23:59:60Z", "error parsing datetime value: date would wrap"},
107+
{"2023-02-28T23:59:60Z", "error parsing datetime value: date would wrap"},
108+
{"1970-01-01T25:00:00Z", "error parsing datetime value: date would wrap"},
109+
{"1970-01-32T00:00:00Z", "error parsing datetime value: date would wrap"},
110+
{"1970-13-01T00:00:00Z", "error parsing datetime value: date would wrap"},
111+
112+
{"1970-01-01T00:00:60Z", "error parsing datetime value: time would wrap"},
113+
{"1970-01-01T00:60:00Z", "error parsing datetime value: time would wrap"},
103114
}
104115
for ti, tt := range tests {
105116
tt := tt

0 commit comments

Comments
 (0)