mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1158399 - Ensure/assert that DateObject::setUTCTime never stores a non-TimeClip'd value in the reserved slot. r=evilpie
This commit is contained in:
parent
c1dad444dd
commit
d88c2a427a
@ -6,10 +6,46 @@
|
||||
#ifndef js_Date_h
|
||||
#define js_Date_h
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/Conversions.h"
|
||||
#include "js/Value.h"
|
||||
|
||||
namespace JS {
|
||||
|
||||
class ClippedTime
|
||||
{
|
||||
double t;
|
||||
|
||||
/* ES5 15.9.1.14. */
|
||||
double timeClip(double time) {
|
||||
/* Steps 1-2. */
|
||||
const double MaxTimeMagnitude = 8.64e15;
|
||||
if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude)
|
||||
return JS::GenericNaN();
|
||||
|
||||
/* Step 3. */
|
||||
return JS::ToInteger(time) + (+0.0);
|
||||
}
|
||||
|
||||
public:
|
||||
ClippedTime() : t(JS::GenericNaN()) {}
|
||||
explicit ClippedTime(double time) : t(timeClip(time)) {}
|
||||
|
||||
static ClippedTime NaN() { return ClippedTime(); }
|
||||
|
||||
double value() const { return t; }
|
||||
};
|
||||
|
||||
inline ClippedTime
|
||||
TimeClip(double d)
|
||||
{
|
||||
return ClippedTime(d);
|
||||
}
|
||||
|
||||
// Year is a year, month is 0-11, day is 1-based. The return value is
|
||||
// a number of milliseconds since the epoch. Can return NaN.
|
||||
JS_PUBLIC_API(double)
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "jit/JitCommon.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "js/Date.h"
|
||||
#include "js/Proxy.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "js/StructuredClone.h"
|
||||
@ -5237,7 +5238,7 @@ JS_NewDateObjectMsec(JSContext* cx, double msec)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return NewDateObjectMsec(cx, msec);
|
||||
return NewDateObjectMsec(cx, JS::TimeClip(msec));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -50,9 +50,12 @@ using namespace js;
|
||||
using mozilla::ArrayLength;
|
||||
using mozilla::IsFinite;
|
||||
using mozilla::IsNaN;
|
||||
using mozilla::NumbersAreIdentical;
|
||||
|
||||
using JS::AutoCheckCannotGC;
|
||||
using JS::ClippedTime;
|
||||
using JS::GenericNaN;
|
||||
using JS::TimeClip;
|
||||
using JS::ToInteger;
|
||||
|
||||
/*
|
||||
@ -350,7 +353,7 @@ MakeDate(double day, double time)
|
||||
JS_PUBLIC_API(double)
|
||||
JS::MakeDate(double year, unsigned month, unsigned day)
|
||||
{
|
||||
return TimeClip(::MakeDate(MakeDay(year, month, day), 0));
|
||||
return TimeClip(::MakeDate(MakeDay(year, month, day), 0)).value();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(double)
|
||||
@ -566,14 +569,6 @@ RegionMatches(const char* s1, int s1off, const CharT* s2, int s2off, int count)
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
/* find UTC time from given date... no 1900 correction! */
|
||||
static double
|
||||
date_msecFromDate(double year, double mon, double mday, double hour,
|
||||
double min, double sec, double msec)
|
||||
{
|
||||
return MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, msec));
|
||||
}
|
||||
|
||||
/* ES6 20.3.3.4. */
|
||||
static bool
|
||||
date_UTC(JSContext* cx, unsigned argc, Value* vp)
|
||||
@ -644,7 +639,8 @@ date_UTC(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
// Step 16.
|
||||
args.rval().setDouble(TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))));
|
||||
ClippedTime time = TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)));
|
||||
args.rval().setDouble(time.value());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -777,7 +773,7 @@ DaysInMonth(int year, int month)
|
||||
*/
|
||||
template <typename CharT>
|
||||
static bool
|
||||
ParseISODate(const CharT* s, size_t length, double* result, DateTimeInfo* dtInfo)
|
||||
ParseISODate(const CharT* s, size_t length, ClippedTime* result, DateTimeInfo* dtInfo)
|
||||
{
|
||||
size_t i = 0;
|
||||
int tzMul = 1;
|
||||
@ -873,19 +869,16 @@ ParseISODate(const CharT* s, size_t length, double* result, DateTimeInfo* dtInfo
|
||||
|
||||
month -= 1; /* convert month to 0-based */
|
||||
|
||||
double msec = date_msecFromDate(dateMul * double(year), month, day,
|
||||
hour, min, sec, frac * 1000.0);
|
||||
double msec = MakeDate(MakeDay(dateMul * double(year), month, day),
|
||||
MakeTime(hour, min, sec, frac * 1000.0));
|
||||
|
||||
if (isLocalTime)
|
||||
msec = UTC(msec, dtInfo);
|
||||
else
|
||||
msec -= tzMul * (tzHour * msPerHour + tzMin * msPerMinute);
|
||||
|
||||
if (msec < -8.64e15 || msec > 8.64e15)
|
||||
return false;
|
||||
|
||||
*result = msec;
|
||||
return true;
|
||||
*result = TimeClip(msec);
|
||||
return NumbersAreIdentical(msec, result->value());
|
||||
|
||||
#undef PEEK
|
||||
#undef NEED
|
||||
@ -895,7 +888,7 @@ ParseISODate(const CharT* s, size_t length, double* result, DateTimeInfo* dtInfo
|
||||
|
||||
template <typename CharT>
|
||||
static bool
|
||||
ParseDate(const CharT* s, size_t length, double* result, DateTimeInfo* dtInfo)
|
||||
ParseDate(const CharT* s, size_t length, ClippedTime* result, DateTimeInfo* dtInfo)
|
||||
{
|
||||
if (ParseISODate(s, length, result, dtInfo))
|
||||
return true;
|
||||
@ -1157,19 +1150,19 @@ ParseDate(const CharT* s, size_t length, double* result, DateTimeInfo* dtInfo)
|
||||
if (hour < 0)
|
||||
hour = 0;
|
||||
|
||||
double msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
|
||||
double msec = MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, 0));
|
||||
|
||||
if (tzOffset == -1) /* no time zone specified, have to use local */
|
||||
msec = UTC(msec, dtInfo);
|
||||
else
|
||||
msec += tzOffset * msPerMinute;
|
||||
|
||||
*result = msec;
|
||||
*result = TimeClip(msec);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ParseDate(JSLinearString* s, double* result, DateTimeInfo* dtInfo)
|
||||
ParseDate(JSLinearString* s, ClippedTime* result, DateTimeInfo* dtInfo)
|
||||
{
|
||||
AutoCheckCannotGC nogc;
|
||||
return s->hasLatin1Chars()
|
||||
@ -1194,45 +1187,44 @@ date_parse(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!linearStr)
|
||||
return false;
|
||||
|
||||
double result;
|
||||
ClippedTime result;
|
||||
if (!ParseDate(linearStr, &result, &cx->runtime()->dateTimeInfo)) {
|
||||
args.rval().setNaN();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = TimeClip(result);
|
||||
args.rval().setNumber(result);
|
||||
args.rval().setDouble(result.value());
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline double
|
||||
static ClippedTime
|
||||
NowAsMillis()
|
||||
{
|
||||
return (double) (PRMJ_Now() / PRMJ_USEC_PER_MSEC);
|
||||
return ClippedTime(static_cast<double>(PRMJ_Now()) / PRMJ_USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
bool
|
||||
js::date_now(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setDouble(NowAsMillis());
|
||||
args.rval().setDouble(NowAsMillis().value());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DateObject::setUTCTime(double t)
|
||||
DateObject::setUTCTime(ClippedTime t)
|
||||
{
|
||||
for (size_t ind = COMPONENTS_START_SLOT; ind < RESERVED_SLOTS; ind++)
|
||||
setReservedSlot(ind, UndefinedValue());
|
||||
|
||||
setFixedSlot(UTC_TIME_SLOT, DoubleValue(t));
|
||||
setFixedSlot(UTC_TIME_SLOT, DoubleValue(t.value()));
|
||||
}
|
||||
|
||||
void
|
||||
DateObject::setUTCTime(double t, MutableHandleValue vp)
|
||||
DateObject::setUTCTime(ClippedTime t, MutableHandleValue vp)
|
||||
{
|
||||
setUTCTime(t);
|
||||
vp.setDouble(t);
|
||||
vp.setDouble(t.value());
|
||||
}
|
||||
|
||||
void
|
||||
@ -1695,7 +1687,7 @@ date_setTime_impl(JSContext* cx, CallArgs args)
|
||||
{
|
||||
Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
|
||||
if (args.length() == 0) {
|
||||
dateObj->setUTCTime(GenericNaN(), args.rval());
|
||||
dateObj->setUTCTime(ClippedTime::NaN(), args.rval());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1760,7 +1752,7 @@ date_setMilliseconds_impl(JSContext* cx, CallArgs args)
|
||||
double time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), milli);
|
||||
|
||||
/* Step 3. */
|
||||
double u = TimeClip(UTC(MakeDate(Day(t), time), &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(MakeDate(Day(t), time), &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 4-5. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -1790,7 +1782,7 @@ date_setUTCMilliseconds_impl(JSContext* cx, CallArgs args)
|
||||
double time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), milli);
|
||||
|
||||
/* Step 3. */
|
||||
double v = TimeClip(MakeDate(Day(t), time));
|
||||
ClippedTime v = TimeClip(MakeDate(Day(t), time));
|
||||
|
||||
/* Steps 4-5. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -1827,7 +1819,7 @@ date_setSeconds_impl(JSContext* cx, CallArgs args)
|
||||
double date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
|
||||
|
||||
/* Step 5. */
|
||||
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 6-7. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -1864,7 +1856,7 @@ date_setUTCSeconds_impl(JSContext* cx, CallArgs args)
|
||||
double date = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli));
|
||||
|
||||
/* Step 5. */
|
||||
double v = TimeClip(date);
|
||||
ClippedTime v = TimeClip(date);
|
||||
|
||||
/* Steps 6-7. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -1906,7 +1898,7 @@ date_setMinutes_impl(JSContext* cx, CallArgs args)
|
||||
double date = MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli));
|
||||
|
||||
/* Step 6. */
|
||||
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 7-8. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -1948,7 +1940,7 @@ date_setUTCMinutes_impl(JSContext* cx, CallArgs args)
|
||||
double date = MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli));
|
||||
|
||||
/* Step 6. */
|
||||
double v = TimeClip(date);
|
||||
ClippedTime v = TimeClip(date);
|
||||
|
||||
/* Steps 7-8. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -1995,7 +1987,7 @@ date_setHours_impl(JSContext* cx, CallArgs args)
|
||||
double date = MakeDate(Day(t), MakeTime(h, m, s, milli));
|
||||
|
||||
/* Step 6. */
|
||||
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 7-8. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -2042,7 +2034,7 @@ date_setUTCHours_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(Day(t), MakeTime(h, m, s, milli));
|
||||
|
||||
/* Step 7. */
|
||||
double v = TimeClip(newDate);
|
||||
ClippedTime v = TimeClip(newDate);
|
||||
|
||||
/* Steps 8-9. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -2074,7 +2066,7 @@ date_setDate_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t));
|
||||
|
||||
/* Step 4. */
|
||||
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 5-6. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -2106,7 +2098,7 @@ date_setUTCDate_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t));
|
||||
|
||||
/* Step 4. */
|
||||
double v = TimeClip(newDate);
|
||||
ClippedTime v = TimeClip(newDate);
|
||||
|
||||
/* Steps 5-6. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -2163,7 +2155,7 @@ date_setMonth_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(YearFromTime(t), m, date), TimeWithinDay(t));
|
||||
|
||||
/* Step 5. */
|
||||
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 6-7. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -2200,7 +2192,7 @@ date_setUTCMonth_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(YearFromTime(t), m, date), TimeWithinDay(t));
|
||||
|
||||
/* Step 5. */
|
||||
double v = TimeClip(newDate);
|
||||
ClippedTime v = TimeClip(newDate);
|
||||
|
||||
/* Steps 6-7. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -2258,7 +2250,7 @@ date_setFullYear_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(y, m, date), TimeWithinDay(t));
|
||||
|
||||
/* Step 6. */
|
||||
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
ClippedTime u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
|
||||
|
||||
/* Steps 7-8. */
|
||||
dateObj->setUTCTime(u, args.rval());
|
||||
@ -2300,7 +2292,7 @@ date_setUTCFullYear_impl(JSContext* cx, CallArgs args)
|
||||
double newDate = MakeDate(MakeDay(y, m, date), TimeWithinDay(t));
|
||||
|
||||
/* Step 6. */
|
||||
double v = TimeClip(newDate);
|
||||
ClippedTime v = TimeClip(newDate);
|
||||
|
||||
/* Steps 7-8. */
|
||||
dateObj->setUTCTime(v, args.rval());
|
||||
@ -2330,7 +2322,7 @@ date_setYear_impl(JSContext* cx, CallArgs args)
|
||||
|
||||
/* Step 3. */
|
||||
if (IsNaN(y)) {
|
||||
dateObj->setUTCTime(GenericNaN(), args.rval());
|
||||
dateObj->setUTCTime(ClippedTime::NaN(), args.rval());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2374,7 +2366,7 @@ static const char * const months[] =
|
||||
static void
|
||||
print_gmt_string(char* buf, size_t size, double utctime)
|
||||
{
|
||||
MOZ_ASSERT(TimeClip(utctime) == utctime);
|
||||
MOZ_ASSERT(NumbersAreIdentical(TimeClip(utctime).value(), utctime));
|
||||
JS_snprintf(buf, size, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
|
||||
days[int(WeekDay(utctime))],
|
||||
int(DateFromTime(utctime)),
|
||||
@ -2388,7 +2380,7 @@ print_gmt_string(char* buf, size_t size, double utctime)
|
||||
static void
|
||||
print_iso_string(char* buf, size_t size, double utctime)
|
||||
{
|
||||
MOZ_ASSERT(TimeClip(utctime) == utctime);
|
||||
MOZ_ASSERT(NumbersAreIdentical(TimeClip(utctime).value(), utctime));
|
||||
JS_snprintf(buf, size, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
|
||||
int(YearFromTime(utctime)),
|
||||
int(MonthFromTime(utctime)) + 1,
|
||||
@ -2402,7 +2394,7 @@ print_iso_string(char* buf, size_t size, double utctime)
|
||||
static void
|
||||
print_iso_extended_string(char* buf, size_t size, double utctime)
|
||||
{
|
||||
MOZ_ASSERT(TimeClip(utctime) == utctime);
|
||||
MOZ_ASSERT(NumbersAreIdentical(TimeClip(utctime).value(), utctime));
|
||||
JS_snprintf(buf, size, "%+.6d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
|
||||
int(YearFromTime(utctime)),
|
||||
int(MonthFromTime(utctime)) + 1,
|
||||
@ -2558,7 +2550,7 @@ date_format(JSContext* cx, double date, formatspec format, MutableHandleValue rv
|
||||
if (!IsFinite(date)) {
|
||||
JS_snprintf(buf, sizeof buf, js_NaN_date_str);
|
||||
} else {
|
||||
MOZ_ASSERT(TimeClip(date) == date);
|
||||
MOZ_ASSERT(NumbersAreIdentical(TimeClip(date).value(), date));
|
||||
|
||||
double local = LocalTime(date, &cx->runtime()->dateTimeInfo);
|
||||
|
||||
@ -2973,9 +2965,9 @@ static const JSFunctionSpec date_methods[] = {
|
||||
};
|
||||
|
||||
static bool
|
||||
NewDateObject(JSContext* cx, const CallArgs& args, double d)
|
||||
NewDateObject(JSContext* cx, const CallArgs& args, ClippedTime t)
|
||||
{
|
||||
JSObject* obj = NewDateObjectMsec(cx, d);
|
||||
JSObject* obj = NewDateObjectMsec(cx, t);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -2984,9 +2976,9 @@ NewDateObject(JSContext* cx, const CallArgs& args, double d)
|
||||
}
|
||||
|
||||
static bool
|
||||
ToDateString(JSContext* cx, const CallArgs& args, double d)
|
||||
ToDateString(JSContext* cx, const CallArgs& args, ClippedTime t)
|
||||
{
|
||||
return date_format(cx, d, FORMATSPEC_FULL, args.rval());
|
||||
return date_format(cx, t.value(), FORMATSPEC_FULL, args.rval());
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -2994,7 +2986,7 @@ DateNoArguments(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.length() == 0);
|
||||
|
||||
double now = NowAsMillis();
|
||||
ClippedTime now = NowAsMillis();
|
||||
|
||||
if (args.isConstructing())
|
||||
return NewDateObject(cx, args, now);
|
||||
@ -3008,7 +3000,7 @@ DateOneArgument(JSContext* cx, const CallArgs& args)
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
|
||||
if (args.isConstructing()) {
|
||||
double d;
|
||||
ClippedTime t;
|
||||
|
||||
if (!ToPrimitive(cx, args[0]))
|
||||
return false;
|
||||
@ -3018,17 +3010,16 @@ DateOneArgument(JSContext* cx, const CallArgs& args)
|
||||
if (!linearStr)
|
||||
return false;
|
||||
|
||||
if (!ParseDate(linearStr, &d, &cx->runtime()->dateTimeInfo))
|
||||
d = GenericNaN();
|
||||
else
|
||||
d = TimeClip(d);
|
||||
if (!ParseDate(linearStr, &t, &cx->runtime()->dateTimeInfo))
|
||||
t = ClippedTime::NaN();
|
||||
} else {
|
||||
double d;
|
||||
if (!ToNumber(cx, args[0], &d))
|
||||
return false;
|
||||
d = TimeClip(d);
|
||||
t = TimeClip(d);
|
||||
}
|
||||
|
||||
return NewDateObject(cx, args, d);
|
||||
return NewDateObject(cx, args, t);
|
||||
}
|
||||
|
||||
return ToDateString(cx, args, NowAsMillis());
|
||||
@ -3131,7 +3122,7 @@ js::DateConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
static bool
|
||||
FinishDateClassInit(JSContext* cx, HandleObject ctor, HandleObject proto)
|
||||
{
|
||||
proto->as<DateObject>().setUTCTime(GenericNaN());
|
||||
proto->as<DateObject>().setUTCTime(ClippedTime::NaN());
|
||||
|
||||
/*
|
||||
* Date.prototype.toGMTString has the same initial value as
|
||||
@ -3173,13 +3164,13 @@ const Class DateObject::class_ = {
|
||||
}
|
||||
};
|
||||
|
||||
JS_FRIEND_API(JSObject*)
|
||||
js::NewDateObjectMsec(JSContext* cx, double msec_time)
|
||||
JSObject*
|
||||
js::NewDateObjectMsec(JSContext* cx, ClippedTime t)
|
||||
{
|
||||
JSObject* obj = NewBuiltinClassInstance(cx, &DateObject::class_);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
obj->as<DateObject>().setUTCTime(msec_time);
|
||||
obj->as<DateObject>().setUTCTime(t);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -3188,8 +3179,8 @@ js::NewDateObject(JSContext* cx, int year, int mon, int mday,
|
||||
int hour, int min, int sec)
|
||||
{
|
||||
MOZ_ASSERT(mon < 12);
|
||||
double msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
|
||||
return NewDateObjectMsec(cx, UTC(msec_time, &cx->runtime()->dateTimeInfo));
|
||||
double msec_time = MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, 0.0));
|
||||
return NewDateObjectMsec(cx, TimeClip(UTC(msec_time, &cx->runtime()->dateTimeInfo)));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
@ -13,9 +13,12 @@
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/Date.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
#include "vm/DateTime.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
@ -26,8 +29,8 @@ namespace js {
|
||||
* Construct a new Date Object from a time value given in milliseconds UTC
|
||||
* since the epoch.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSObject*)
|
||||
NewDateObjectMsec(JSContext* cx, double msec_time);
|
||||
extern JSObject*
|
||||
NewDateObjectMsec(JSContext* cx, JS::ClippedTime t);
|
||||
|
||||
/*
|
||||
* Construct a new Date Object from an exploded local time value.
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "js/Date.h"
|
||||
#include "js/Value.h"
|
||||
|
||||
namespace js {
|
||||
@ -46,8 +47,8 @@ class DateObject : public NativeObject
|
||||
}
|
||||
|
||||
// Set UTC time to a given time and invalidate cached local time.
|
||||
void setUTCTime(double t);
|
||||
void setUTCTime(double t, MutableHandleValue vp);
|
||||
void setUTCTime(JS::ClippedTime t);
|
||||
void setUTCTime(JS::ClippedTime t, MutableHandleValue vp);
|
||||
|
||||
inline double cachedLocalTime(DateTimeInfo* dtInfo);
|
||||
|
||||
|
@ -39,19 +39,6 @@ const unsigned SecondsPerDay = SecondsPerHour * 24;
|
||||
|
||||
const double StartOfTime = -8.64e15;
|
||||
const double EndOfTime = 8.64e15;
|
||||
const double MaxTimeMagnitude = 8.64e15;
|
||||
|
||||
/* ES5 15.9.1.14. */
|
||||
inline double
|
||||
TimeClip(double time)
|
||||
{
|
||||
/* Steps 1-2. */
|
||||
if (!mozilla::IsFinite(time) || mozilla::Abs(time) > MaxTimeMagnitude)
|
||||
return JS::GenericNaN();
|
||||
|
||||
/* Step 3. */
|
||||
return JS::ToInteger(time + (+0.0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores date/time information, particularly concerning the current local
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "js/Date.h"
|
||||
#include "vm/SharedArrayObject.h"
|
||||
#include "vm/TypedArrayObject.h"
|
||||
#include "vm/WrapperObject.h"
|
||||
@ -53,6 +54,7 @@ using mozilla::BitwiseCast;
|
||||
using mozilla::IsNaN;
|
||||
using mozilla::LittleEndian;
|
||||
using mozilla::NativeEndian;
|
||||
using mozilla::NumbersAreIdentical;
|
||||
using JS::CanonicalizeNaN;
|
||||
|
||||
// When you make updates here, make sure you consider whether you need to bump the
|
||||
@ -1591,12 +1593,13 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
|
||||
double d;
|
||||
if (!in.readDouble(&d) || !checkDouble(d))
|
||||
return false;
|
||||
if (!IsNaN(d) && d != TimeClip(d)) {
|
||||
JS::ClippedTime t = JS::TimeClip(d);
|
||||
if (!NumbersAreIdentical(d, t.value())) {
|
||||
JS_ReportErrorNumber(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA, "date");
|
||||
return false;
|
||||
}
|
||||
JSObject* obj = NewDateObjectMsec(context(), d);
|
||||
JSObject* obj = NewDateObjectMsec(context(), t);
|
||||
if (!obj)
|
||||
return false;
|
||||
vp.setObject(*obj);
|
||||
|
Loading…
Reference in New Issue
Block a user