mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1160356 - Make new Date(arg1, arg2, ...) conform to ES3-6 in converting *all* arguments to number before computing the return value. r=evilpie
This commit is contained in:
parent
f363b3b6d4
commit
01dc5627a5
@ -574,46 +574,6 @@ date_msecFromDate(double year, double mon, double mday, double hour,
|
||||
return MakeDate(MakeDay(year, mon, mday), MakeTime(hour, min, sec, msec));
|
||||
}
|
||||
|
||||
/* compute the time in msec (unclipped) from the given args */
|
||||
#define MAXARGS 7
|
||||
|
||||
static bool
|
||||
date_msecFromArgs(JSContext* cx, CallArgs args, double* rval)
|
||||
{
|
||||
unsigned loop;
|
||||
double array[MAXARGS];
|
||||
double msec_time;
|
||||
|
||||
for (loop = 0; loop < MAXARGS; loop++) {
|
||||
if (loop < args.length()) {
|
||||
double d;
|
||||
if (!ToNumber(cx, args[loop], &d))
|
||||
return false;
|
||||
/* return NaN if any arg is not finite */
|
||||
if (!IsFinite(d)) {
|
||||
*rval = GenericNaN();
|
||||
return true;
|
||||
}
|
||||
array[loop] = ToInteger(d);
|
||||
} else {
|
||||
if (loop == 2) {
|
||||
array[loop] = 1; /* Default the date argument to 1. */
|
||||
} else {
|
||||
array[loop] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust 2-digit years into the 20th century */
|
||||
if (array[0] >= 0 && array[0] <= 99)
|
||||
array[0] += 1900;
|
||||
|
||||
msec_time = date_msecFromDate(array[0], array[1], array[2],
|
||||
array[3], array[4], array[5], array[6]);
|
||||
*rval = msec_time;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES6 20.3.3.4. */
|
||||
static bool
|
||||
date_UTC(JSContext* cx, unsigned argc, Value* vp)
|
||||
@ -2947,7 +2907,7 @@ js::date_valueOf(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
static const JSFunctionSpec date_static_methods[] = {
|
||||
JS_FN("UTC", date_UTC, MAXARGS,0),
|
||||
JS_FN("UTC", date_UTC, 7,0),
|
||||
JS_FN("parse", date_parse, 1,0),
|
||||
JS_FN("now", date_now, 0,0),
|
||||
JS_FS_END
|
||||
@ -3079,17 +3039,76 @@ DateMultipleArguments(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(args.length() >= 2);
|
||||
|
||||
// Step 3.
|
||||
if (args.isConstructing()) {
|
||||
double millis;
|
||||
if (!date_msecFromArgs(cx, args, &millis))
|
||||
// Steps 3a-b.
|
||||
double y;
|
||||
if (!ToNumber(cx, args[0], &y))
|
||||
return false;
|
||||
|
||||
if (IsFinite(millis)) {
|
||||
millis = UTC(millis, &cx->runtime()->dateTimeInfo);
|
||||
millis = TimeClip(millis);
|
||||
// Steps 3c-d.
|
||||
double m;
|
||||
if (!ToNumber(cx, args[1], &m))
|
||||
return false;
|
||||
|
||||
// Steps 3e-f.
|
||||
double dt;
|
||||
if (args.length() >= 3) {
|
||||
if (!ToNumber(cx, args[2], &dt))
|
||||
return false;
|
||||
} else {
|
||||
dt = 1;
|
||||
}
|
||||
|
||||
return NewDateObject(cx, args, millis);
|
||||
// Steps 3g-h.
|
||||
double h;
|
||||
if (args.length() >= 4) {
|
||||
if (!ToNumber(cx, args[3], &h))
|
||||
return false;
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
// Steps 3i-j.
|
||||
double min;
|
||||
if (args.length() >= 5) {
|
||||
if (!ToNumber(cx, args[4], &min))
|
||||
return false;
|
||||
} else {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
// Steps 3k-l.
|
||||
double s;
|
||||
if (args.length() >= 6) {
|
||||
if (!ToNumber(cx, args[5], &s))
|
||||
return false;
|
||||
} else {
|
||||
s = 0;
|
||||
}
|
||||
|
||||
// Steps 3m-n.
|
||||
double milli;
|
||||
if (args.length() >= 7) {
|
||||
if (!ToNumber(cx, args[6], &milli))
|
||||
return false;
|
||||
} else {
|
||||
milli = 0;
|
||||
}
|
||||
|
||||
// Step 3o.
|
||||
double yr = y;
|
||||
if (!IsNaN(y)) {
|
||||
double yint = ToInteger(y);
|
||||
if (0 <= yint && yint <= 99)
|
||||
yr = 1900 + yint;
|
||||
}
|
||||
|
||||
// Step 3p.
|
||||
double finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli));
|
||||
|
||||
// Steps 3q-t.
|
||||
return NewDateObject(cx, args, TimeClip(UTC(finalDate, &cx->runtime()->dateTimeInfo)));
|
||||
}
|
||||
|
||||
return ToDateString(cx, args, NowAsMillis());
|
||||
@ -3144,7 +3163,7 @@ const Class DateObject::class_ = {
|
||||
nullptr, /* construct */
|
||||
nullptr, /* trace */
|
||||
{
|
||||
GenericCreateConstructor<DateConstructor, MAXARGS, JSFunction::FinalizeKind>,
|
||||
GenericCreateConstructor<DateConstructor, 7, JSFunction::FinalizeKind>,
|
||||
GenericCreatePrototype,
|
||||
date_static_methods,
|
||||
nullptr,
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommonn.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var BUGNUMBER = 1160356;
|
||||
var summary =
|
||||
"new Date(...) must convert *all* arguments to number, not return NaN " +
|
||||
"early if a non-finite argument is encountered";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
function expectThrowTypeError(f, i)
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
throw new Error("didn't throw");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
assertEq(e, 42, "index " + i + ": expected 42, got " + e);
|
||||
}
|
||||
}
|
||||
|
||||
var bad =
|
||||
{ toString: function() { throw 17; }, valueOf: function() { throw 42; } };
|
||||
|
||||
var funcs =
|
||||
[
|
||||
function() { new Date(bad); },
|
||||
|
||||
function() { new Date(NaN, bad); },
|
||||
function() { new Date(Infinity, bad); },
|
||||
function() { new Date(1970, bad); },
|
||||
|
||||
function() { new Date(1970, NaN, bad); },
|
||||
function() { new Date(1970, Infinity, bad); },
|
||||
function() { new Date(1970, 4, bad); },
|
||||
|
||||
function() { new Date(1970, 4, NaN, bad); },
|
||||
function() { new Date(1970, 4, Infinity, bad); },
|
||||
function() { new Date(1970, 4, 17, bad); },
|
||||
|
||||
function() { new Date(1970, 4, 17, NaN, bad); },
|
||||
function() { new Date(1970, 4, 17, Infinity, bad); },
|
||||
function() { new Date(1970, 4, 17, 13, bad); },
|
||||
|
||||
function() { new Date(1970, 4, 17, 13, NaN, bad); },
|
||||
function() { new Date(1970, 4, 17, 13, Infinity, bad); },
|
||||
function() { new Date(1970, 4, 17, 13, 37, bad); },
|
||||
|
||||
function() { new Date(1970, 4, 17, 13, 37, NaN, bad); },
|
||||
function() { new Date(1970, 4, 17, 13, 37, Infinity, bad); },
|
||||
function() { new Date(1970, 4, 17, 13, 37, 23, bad); },
|
||||
];
|
||||
|
||||
for (var i = 0, len = funcs.length; i < len; i++)
|
||||
expectThrowTypeError(funcs[i]);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
Loading…
Reference in New Issue
Block a user