-
Notifications
You must be signed in to change notification settings - Fork 481
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Temporal: Prevent arbitrary loops in NormalizedTimeDurationToDays
Adapts the tests that checked arbitrarily long loops, to now check that an exception is thrown if the loop would happen. Adds tests that exercise the newly added checks on return values of getPossibleInstantsFor and getOffsetNanosecondsFor that limit UTC offset shifts to 24 hours or less. Also updates some step numbers in related tests.
- Loading branch information
Showing
73 changed files
with
2,960 additions
and
413 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
...ns/Temporal/Duration/compare/relativeto-propertybag-out-of-range-backward-offset-shift.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,48 @@ | ||
// Copyright (C) 2024 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.compare | ||
description: > | ||
UTC offset shift returned by getPossibleInstantsFor can be at most 24 hours. | ||
features: [Temporal] | ||
info: | | ||
GetPossibleInstantsFor: | ||
5.b.i. Let _numResults_ be _list_'s length. | ||
ii. If _numResults_ > 1, then | ||
1. Let _epochNs_ be a new empty List. | ||
2. For each value _instant_ in list, do | ||
a. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_. | ||
3. Let _min_ be the least element of the List _epochNs_. | ||
4. Let _max_ be the greatest element of the List _epochNs_. | ||
5. If abs(ℝ(_max_ - _min_)) > nsPerDay, throw a *RangeError* exception. | ||
---*/ | ||
|
||
class ShiftLonger24Hour extends Temporal.TimeZone { | ||
id = 'TestTimeZone'; | ||
|
||
constructor() { | ||
super('UTC'); | ||
} | ||
|
||
getOffsetNanosecondsFor(instant) { | ||
return 0; | ||
} | ||
|
||
getPossibleInstantsFor(plainDateTime) { | ||
const utc = new Temporal.TimeZone("UTC"); | ||
const [utcInstant] = utc.getPossibleInstantsFor(plainDateTime); | ||
return [ | ||
utcInstant.subtract({ hours: 12, nanoseconds: 1 }), | ||
utcInstant.add({ hours: 12 }), | ||
utcInstant, // add a third value in case the implementation doesn't sort | ||
]; | ||
} | ||
} | ||
|
||
const timeZone = new ShiftLonger24Hour(); | ||
const relativeTo = { year: 1970, month: 1, day: 1, hour: 12, timeZone }; | ||
const duration1 = new Temporal.Duration(1); | ||
const duration2 = new Temporal.Duration(2); | ||
|
||
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, {relativeTo: relativeTo}), "RangeError should be thrown"); |
43 changes: 43 additions & 0 deletions
43
...ins/Temporal/Duration/compare/relativeto-propertybag-out-of-range-forward-offset-shift.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,43 @@ | ||
// Copyright (C) 2024 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.compare | ||
description: > | ||
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor | ||
in DisambiguatePossibleInstants cannot be greater than 24 hours. | ||
features: [Temporal] | ||
info: | | ||
DisambiguatePossibleInstants: | ||
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception. | ||
---*/ | ||
|
||
class ShiftLonger24Hour extends Temporal.TimeZone { | ||
id = 'TestTimeZone'; | ||
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z | ||
|
||
constructor() { | ||
super('UTC'); | ||
} | ||
|
||
getOffsetNanosecondsFor(instant) { | ||
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9; | ||
return 12 * 3600e9 + 1; | ||
} | ||
|
||
getPossibleInstantsFor(plainDateTime) { | ||
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime); | ||
const { year, month, day } = plainDateTime; | ||
|
||
if (year < 1970) return [utcInstant.subtract({ hours: 12 })]; | ||
if (year === 1970 && month === 1 && day === 1) return []; | ||
return [utcInstant.add({ hours: 12, nanoseconds: 1 })]; | ||
} | ||
} | ||
|
||
const timeZone = new ShiftLonger24Hour(); | ||
const relativeTo = { year: 1970, month: 1, day: 1, hour: 12, timeZone }; | ||
const duration1 = new Temporal.Duration(1); | ||
const duration2 = new Temporal.Duration(2); | ||
|
||
assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, {relativeTo: relativeTo}), "RangeError should be thrown"); |
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
47 changes: 47 additions & 0 deletions
47
...poral/Duration/prototype/add/relativeto-propertybag-out-of-range-backward-offset-shift.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,47 @@ | ||
// Copyright (C) 2024 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.add | ||
description: > | ||
UTC offset shift returned by getPossibleInstantsFor can be at most 24 hours. | ||
features: [Temporal] | ||
info: | | ||
GetPossibleInstantsFor: | ||
5.b.i. Let _numResults_ be _list_'s length. | ||
ii. If _numResults_ > 1, then | ||
1. Let _epochNs_ be a new empty List. | ||
2. For each value _instant_ in list, do | ||
a. Append _instant_.[[EpochNanoseconds]] to the end of the List _epochNs_. | ||
3. Let _min_ be the least element of the List _epochNs_. | ||
4. Let _max_ be the greatest element of the List _epochNs_. | ||
5. If abs(ℝ(_max_ - _min_)) > nsPerDay, throw a *RangeError* exception. | ||
---*/ | ||
|
||
class ShiftLonger24Hour extends Temporal.TimeZone { | ||
id = 'TestTimeZone'; | ||
|
||
constructor() { | ||
super('UTC'); | ||
} | ||
|
||
getOffsetNanosecondsFor(instant) { | ||
return 0; | ||
} | ||
|
||
getPossibleInstantsFor(plainDateTime) { | ||
const utc = new Temporal.TimeZone("UTC"); | ||
const [utcInstant] = utc.getPossibleInstantsFor(plainDateTime); | ||
return [ | ||
utcInstant.subtract({ hours: 12, nanoseconds: 1 }), | ||
utcInstant.add({ hours: 12 }), | ||
utcInstant, // add a third value in case the implementation doesn't sort | ||
]; | ||
} | ||
} | ||
|
||
const timeZone = new ShiftLonger24Hour(); | ||
const relativeTo = { year: 1970, month: 1, day: 1, hour: 12, timeZone }; | ||
|
||
const instance = new Temporal.Duration(1, 0, 0, 1); | ||
assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), "RangeError should be thrown"); |
42 changes: 42 additions & 0 deletions
42
...mporal/Duration/prototype/add/relativeto-propertybag-out-of-range-forward-offset-shift.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,42 @@ | ||
// Copyright (C) 2024 Igalia, S.L. All rights reserved. | ||
// This code is governed by the BSD license found in the LICENSE file. | ||
|
||
/*--- | ||
esid: sec-temporal.duration.prototype.add | ||
description: > | ||
UTC offset shift returned by adjacent invocations of getOffsetNanosecondsFor | ||
in DisambiguatePossibleInstants cannot be greater than 24 hours. | ||
features: [Temporal] | ||
info: | | ||
DisambiguatePossibleInstants: | ||
18. If abs(_nanoseconds_) > nsPerDay, throw a *RangeError* exception. | ||
---*/ | ||
|
||
class ShiftLonger24Hour extends Temporal.TimeZone { | ||
id = 'TestTimeZone'; | ||
_shiftEpochNs = 12n * 3600n * 1_000_000_000n; // 1970-01-01T12:00Z | ||
|
||
constructor() { | ||
super('UTC'); | ||
} | ||
|
||
getOffsetNanosecondsFor(instant) { | ||
if (instant.epochNanoseconds < this._shiftEpochNs) return -12 * 3600e9; | ||
return 12 * 3600e9 + 1; | ||
} | ||
|
||
getPossibleInstantsFor(plainDateTime) { | ||
const [utcInstant] = super.getPossibleInstantsFor(plainDateTime); | ||
const { year, month, day } = plainDateTime; | ||
|
||
if (year < 1970) return [utcInstant.subtract({ hours: 12 })]; | ||
if (year === 1970 && month === 1 && day === 1) return []; | ||
return [utcInstant.add({ hours: 12, nanoseconds: 1 })]; | ||
} | ||
} | ||
|
||
const timeZone = new ShiftLonger24Hour(); | ||
const relativeTo = { year: 1970, month: 1, day: 1, hour: 12, timeZone }; | ||
|
||
const instance = new Temporal.Duration(1, 0, 0, 1); | ||
assert.throws(RangeError, () => instance.add(new Temporal.Duration(0, 0, 0, 0, -24), { relativeTo }), "RangeError should be thrown"); |
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
Oops, something went wrong.