From b1c8029c2bb957e40d3018885a0ae4f7da333006 Mon Sep 17 00:00:00 2001 From: Moustafa Raafat Date: Fri, 21 Oct 2022 22:36:35 +0100 Subject: [PATCH] LibJS: Require that NanosecondsToDays doesn't flip sign This is an normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/e13c52d --- Userland/Libraries/LibJS/Runtime/ErrorTypes.h | 4 ++++ .../LibJS/Runtime/Temporal/ZonedDateTime.cpp | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h index 53e2f28d22..d70cbd8a5b 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h @@ -269,6 +269,10 @@ M(TemporalMissingOptionsObject, "Required options object is missing or undefined") \ M(TemporalMissingStartingPoint, "A starting point is required for balancing {}") \ M(TemporalMissingUnits, "One or both of smallestUnit or largestUnit is required") \ + M(TemporalNanosecondsConvertedToDaysWithOppositeSign, "Time zone or calendar converted nanoseconds into a number of days with " \ + "the opposite sign") \ + M(TemporalNanosecondsConvertedToRemainderOfNanosecondsWithOppositeSign, "Time zone or calendar ended up with a remainder of " \ + "nanoseconds with the opposite sign") \ M(TemporalObjectMustHaveOneOf, "Object must have at least one of the following properties: {}") \ M(TemporalObjectMustNotHave, "Object must not have a defined {} property") \ M(TemporalPropertyMustBeFinite, "Property must not be Infinity") \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp index 4507b78ecc..da795b75dc 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp @@ -538,7 +538,23 @@ ThrowCompletionOr nanoseconds_to_days(VM& vm, Crypto::S } } - // 19. Return the Record { [[Days]]: days, [[Nanoseconds]]: nanoseconds, [[DayLength]]: abs(dayLengthNs) }. + // 19. If days < 0 and sign = 1, throw a RangeError exception. + if (days < 0 && sign == 1) + return vm.throw_completion(ErrorType::TemporalNanosecondsConvertedToDaysWithOppositeSign); + + // 20. If days > 0 and sign = -1, throw a RangeError exception. + if (days > 0 && sign == -1) + return vm.throw_completion(ErrorType::TemporalNanosecondsConvertedToDaysWithOppositeSign); + + // 21. If nanoseconds < 0 and sign = 1, throw a RangeError exception. + if (nanoseconds.is_negative() && sign == 1) + return vm.throw_completion(ErrorType::TemporalNanosecondsConvertedToRemainderOfNanosecondsWithOppositeSign); + + // 22. If nanoseconds > 0 and sign = -1, throw a RangeError exception. + if (nanoseconds.is_positive() && sign == -1) + return vm.throw_completion(ErrorType::TemporalNanosecondsConvertedToRemainderOfNanosecondsWithOppositeSign); + + // 23. Return the Record { [[Days]]: days, [[Nanoseconds]]: nanoseconds, [[DayLength]]: abs(dayLengthNs) }. return NanosecondsToDaysResult { .days = days, .nanoseconds = move(nanoseconds), .day_length = fabs(day_length_ns.to_double()) }; }