Skip to content

Commit 2b4cbb2

Browse files
authored
Reject IsoDate when outside the allowed range (#62)
Maybe we could move the check to `IsoDate`'s constructor? For now this is enough to pass test262.
1 parent 7f5da3b commit 2b4cbb2

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

src/components/date.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,4 +797,54 @@ mod tests {
797797
let result = later.since(&earlier, None, None, None, None).unwrap();
798798
assert_eq!(result.days(), 9719.0,);
799799
}
800+
801+
// test262/test/built-ins/Temporal/Calendar/prototype/month/argument-string-invalid.js
802+
#[test]
803+
fn invalid_strings() {
804+
const INVALID_STRINGS: [&str; 35] = [
805+
// invalid ISO strings:
806+
"",
807+
"invalid iso8601",
808+
"2020-01-00",
809+
"2020-01-32",
810+
"2020-02-30",
811+
"2021-02-29",
812+
"2020-00-01",
813+
"2020-13-01",
814+
"2020-01-01T",
815+
"2020-01-01T25:00:00",
816+
"2020-01-01T01:60:00",
817+
"2020-01-01T01:60:61",
818+
"2020-01-01junk",
819+
"2020-01-01T00:00:00junk",
820+
"2020-01-01T00:00:00+00:00junk",
821+
"2020-01-01T00:00:00+00:00[UTC]junk",
822+
"2020-01-01T00:00:00+00:00[UTC][u-ca=iso8601]junk",
823+
"02020-01-01",
824+
"2020-001-01",
825+
"2020-01-001",
826+
"2020-01-01T001",
827+
"2020-01-01T01:001",
828+
"2020-01-01T01:01:001",
829+
// valid, but forms not supported in Temporal:
830+
"2020-W01-1",
831+
"2020-001",
832+
"+0002020-01-01",
833+
// valid, but this calendar must not exist:
834+
"2020-01-01[u-ca=notexist]",
835+
// may be valid in other contexts, but insufficient information for PlainDate:
836+
"2020-01",
837+
"+002020-01",
838+
"01-01",
839+
"2020-W01",
840+
"P1Y",
841+
"-P12Y",
842+
// valid, but outside the supported range:
843+
"-999999-01-01",
844+
"+999999-01-01",
845+
];
846+
for s in INVALID_STRINGS {
847+
assert!(Date::<()>::from_str(s).is_err())
848+
}
849+
}
800850
}

src/iso.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,22 +200,30 @@ impl IsoDate {
200200
day: i32,
201201
overflow: ArithmeticOverflow,
202202
) -> TemporalResult<Self> {
203-
match overflow {
203+
let id = match overflow {
204204
ArithmeticOverflow::Constrain => {
205205
let month = month.clamp(1, 12);
206206
let days_in_month = utils::iso_days_in_month(year, month);
207207
let d = day.clamp(1, days_in_month);
208208
// NOTE: Values are clamped in a u8 range.
209-
Ok(Self::new_unchecked(year, month as u8, d as u8))
209+
Self::new_unchecked(year, month as u8, d as u8)
210210
}
211211
ArithmeticOverflow::Reject => {
212212
if !is_valid_date(year, month, day) {
213213
return Err(TemporalError::range().with_message("not a valid ISO date."));
214214
}
215215
// NOTE: Values have been verified to be in a u8 range.
216-
Ok(Self::new_unchecked(year, month as u8, day as u8))
216+
Self::new_unchecked(year, month as u8, day as u8)
217217
}
218+
};
219+
220+
if !iso_dt_within_valid_limits(id, &IsoTime::noon()) {
221+
return Err(
222+
TemporalError::range().with_message("Date is not within ISO date time limits.")
223+
);
218224
}
225+
226+
Ok(id)
219227
}
220228

221229
/// Create a balanced `IsoDate`

src/rounding.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<T: Roundable> IncrementRounder<T> {
5757
pub(crate) fn from_positive_parts(number: T, increment: NonZeroU64) -> TemporalResult<Self> {
5858
let increment = <T as NumCast>::from(increment.get()).temporal_unwrap()?;
5959

60-
debug_assert!(number > T::ZERO);
60+
debug_assert!(number >= T::ZERO);
6161

6262
Ok(Self {
6363
sign: true,

0 commit comments

Comments
 (0)