-
Notifications
You must be signed in to change notification settings - Fork 470
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Temporal: Limit year, month, and week length calculations to nonzero
Tests with conditions that would trip a division by zero in implementations if they didn't carefully implement the spec.
- Loading branch information
Showing
10 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
test/built-ins/Temporal/Duration/prototype/round/zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.round | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const instance = new Temporal.Duration(1, 0, 0, 0, 0, 0, 0, 0, 0, 1); | ||
const relativeTo = new Temporal.ZonedDateTime(0n, "UTC", cal); | ||
|
||
assert.throws(RangeError, () => instance.round({ relativeTo, smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => instance.round({ relativeTo, smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => instance.round({ relativeTo, smallestUnit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
test/built-ins/Temporal/Duration/prototype/total/zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.total | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const instance = new Temporal.Duration(1, 0, 0, 0, 0, 0, 0, 0, 0, 1); | ||
const relativeTo = new Temporal.ZonedDateTime(0n, "UTC", cal); | ||
|
||
assert.throws(RangeError, () => instance.total({ relativeTo, unit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => instance.total({ relativeTo, unit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => instance.total({ relativeTo, unit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
test/built-ins/Temporal/PlainDate/prototype/since/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plaindate.prototype.since | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const d1 = new Temporal.PlainDate(1970, 1, 1, cal); | ||
const d2 = new Temporal.PlainDate(1971, 1, 1, cal); | ||
|
||
assert.throws(RangeError, () => d1.since(d2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => d1.since(d2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => d1.since(d2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
test/built-ins/Temporal/PlainDate/prototype/until/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plaindate.prototype.until | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const d1 = new Temporal.PlainDate(1970, 1, 1, cal); | ||
const d2 = new Temporal.PlainDate(1971, 1, 1, cal); | ||
|
||
assert.throws(RangeError, () => d1.until(d2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => d1.until(d2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => d1.until(d2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
.../built-ins/Temporal/PlainDateTime/prototype/since/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plaindatetime.prototype.since | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal); | ||
const dt2 = new Temporal.PlainDateTime(1971, 1, 1, 0, 0, 0, 0, 0, 1, cal); | ||
|
||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
.../built-ins/Temporal/PlainDateTime/prototype/until/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plaindatetime.prototype.until | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const dt1 = new Temporal.PlainDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, cal); | ||
const dt2 = new Temporal.PlainDateTime(1971, 1, 1, 0, 0, 0, 0, 0, 1, cal); | ||
|
||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |
30 changes: 30 additions & 0 deletions
30
test/built-ins/Temporal/PlainYearMonth/prototype/since/rounding-zero-year-month-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plainyearmonth.prototype.since | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const ym1 = new Temporal.PlainYearMonth(1970, 1, cal); | ||
const ym2 = new Temporal.PlainYearMonth(1971, 1, cal); | ||
|
||
assert.throws(RangeError, () => ym1.since(ym2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => ym1.since(ym2, { smallestUnit: "months", roundingIncrement: 2 }), "zero month length handled correctly"); |
30 changes: 30 additions & 0 deletions
30
test/built-ins/Temporal/PlainYearMonth/prototype/until/rounding-zero-year-month-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.plainyearmonth.prototype.until | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const ym1 = new Temporal.PlainYearMonth(1970, 1, cal); | ||
const ym2 = new Temporal.PlainYearMonth(1971, 1, cal); | ||
|
||
assert.throws(RangeError, () => ym1.until(ym2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => ym1.until(ym2, { smallestUnit: "months", roundingIncrement: 2 }), "zero month length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
.../built-ins/Temporal/ZonedDateTime/prototype/since/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.zoneddatetime.prototype.since | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const dt1 = new Temporal.ZonedDateTime(0n, "UTC", cal); | ||
const dt2 = new Temporal.ZonedDateTime(365n * 86400_000_000_000n + 1n, "UTC", cal); | ||
|
||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => dt1.since(dt2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |
31 changes: 31 additions & 0 deletions
31
.../built-ins/Temporal/ZonedDateTime/prototype/until/rounding-zero-year-month-week-length.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright (C) 2023 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.zoneddatetime.prototype.until | ||
description: > | ||
A malicious calendar resulting in a year, month, or week length of zero is | ||
handled correctly | ||
info: | | ||
RoundDuration | ||
10.z. If _oneYearDays_ = 0, throw a *RangeError* exception. | ||
... | ||
11.z. If _oneMonthDays_ = 0, throw a *RangeError* exception. | ||
... | ||
12.s. If _oneWeekDays_ = 0, throw a *RangeError* exception. | ||
features: [Temporal] | ||
---*/ | ||
|
||
const cal = new class extends Temporal.Calendar { | ||
dateAdd(date, duration, options) { | ||
// Called several times, last call sets oneYear/Month/WeekDays to 0 | ||
return new Temporal.PlainDate(1970, 1, 1); | ||
} | ||
}("iso8601"); | ||
|
||
const dt1 = new Temporal.ZonedDateTime(0n, "UTC", cal); | ||
const dt2 = new Temporal.ZonedDateTime(365n * 86400_000_000_000n + 1n, "UTC", cal); | ||
|
||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "years" }), "zero year length handled correctly"); | ||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "months" }), "zero month length handled correctly"); | ||
assert.throws(RangeError, () => dt1.until(dt2, { smallestUnit: "weeks" }), "zero week length handled correctly"); |