Skip to content

Commit c2f00f6

Browse files
Reject tz offset minutes >=60 (#581)
Signed-off-by: John Kastner <[email protected]>
1 parent 5bc083f commit c2f00f6

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

cedar-lean/Cedar/Spec/Ext/Datetime.lean

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@ def datetime? (i: Int) : Option Datetime :=
8080
def dateContainsLeapSeconds (str: String) : Bool :=
8181
str.length >= 20 && str.get? ⟨17⟩ == some '6' && str.get? ⟨18⟩ == some '0'
8282

83+
/--
84+
Check that the minutes for the timezone offset are in bounds (<60). We
85+
separately check that the whole offset is less than `MAX_OFFSET_SECONDS` which
86+
ensures that the hour component is in bounds. The timezone offset does not
87+
have a seconds component.
88+
-/
89+
def tzOffsetMinsLt60 (str : String) : Bool :=
90+
-- Short string is `DateOnly`, so no offset
91+
str.length <= 10 ||
92+
-- Ends in `Z` is either `DateUTC` or `DateUTCWithMillis`, so no offset
93+
str.endsWith "Z" ||
94+
-- `DateWithOffset` or `DateWithOffsetAndMillis` offset is last 4 chars.
95+
-- Minutes component is last two chars.
96+
match (str.takeRight 2).toNat? with
97+
| .some minsOffset => minsOffset < 60
98+
| .none => false
99+
83100
/--
84101
Workaround an issue in the datetime library by checking that the year, month,
85102
day, hour, minute, and second components of the datetime string are not longer
@@ -107,6 +124,7 @@ def checkComponentLen (str : String) : Bool :=
107124
def parse (str: String) : Option Datetime := do
108125
if dateContainsLeapSeconds str then failure
109126
if !checkComponentLen str then failure
127+
if !tzOffsetMinsLt60 str then failure
110128
let val :=
111129
DateOnly.parse str <|>
112130
DateUTC.parse str <|>

cedar-lean/UnitTest/Datetime.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ def testsForInvalidDatetimeStrings :=
108108
testInvalidDatetime "2024-01-01T00:00:00.001➕0000" "sign `-` is an emoji",
109109
testInvalidDatetime "2024-01-01T00:00:00.001+00000" "offset is 5 digits",
110110
testInvalidDatetime "2024-01-01T00:00:00.001-00000" "offset is 5 digits",
111-
testInvalidDatetime "2016-12-31T00:00:00+2400" "invalid offset range",
112-
testInvalidDatetime "2016-12-31T00:00:00+9999" "invalid offset range",
111+
testInvalidDatetime "2016-01-01T00:00:00+2400" "invalid offset hour range",
112+
testInvalidDatetime "2016-01-01T00:00:00+0060" "invalid offset minute range",
113+
testInvalidDatetime "2016-01-01T00:00:00+9999" "invalid offset hour and minute range",
113114
]
114115

115116
-- Note: The instances below are only used for tests.

0 commit comments

Comments
 (0)