Bug 1160356 - Make Date.UTC conform to ES3-6 in converting *all* arguments to number before computing the return value. r=evilpie
authorJeff Walden <jwalden@mit.edu>
Thu, 30 Apr 2015 09:58:58 -0700
changeset 242119 9804500b0ab7f9bcaa9037fff7458bb80cd6402a
parent 242118 fc1b65394523d0d22e2b0671f5cffb90a7b0fbc5
child 242120 a411bd3307dac2f43d9feadd9653fc0a4917e94a
push id28679
push userphilringnalda@gmail.com
push dateSat, 02 May 2015 17:02:29 +0000
treeherdermozilla-central@0f5eacc986e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1160356
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1160356 - Make Date.UTC conform to ES3-6 in converting *all* arguments to number before computing the return value. r=evilpie
js/src/jsdate.cpp
js/src/tests/ecma_5/Date/UTC-convert-all-arguments.js
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -609,31 +609,87 @@ date_msecFromArgs(JSContext* cx, CallArg
         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;
 }
 
-/*
- * See ECMA 15.9.4.[3-10];
- */
+/* ES6 20.3.3.4. */
 static bool
 date_UTC(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
-    double msec_time;
-    if (!date_msecFromArgs(cx, args, &msec_time))
+    // Steps 1-2.
+    double y;
+    if (!ToNumber(cx, args.get(0), &y))
+        return false;
+
+    // Steps 3-4.
+    double m;
+    if (!ToNumber(cx, args.get(1), &m))
         return false;
 
-    msec_time = TimeClip(msec_time);
-
-    args.rval().setNumber(msec_time);
+    // Steps 5-6.
+    double dt;
+    if (args.length() >= 3) {
+        if (!ToNumber(cx, args[2], &dt))
+            return false;
+    } else {
+        dt = 1;
+    }
+
+    // Steps 7-8.
+    double h;
+    if (args.length() >= 4) {
+        if (!ToNumber(cx, args[3], &h))
+            return false;
+    } else {
+        h = 0;
+    }
+
+    // Steps 9-10.
+    double min;
+    if (args.length() >= 5) {
+        if (!ToNumber(cx, args[4], &min))
+            return false;
+    } else {
+        min = 0;
+    }
+
+    // Steps 11-12.
+    double s;
+    if (args.length() >= 6) {
+        if (!ToNumber(cx, args[5], &s))
+            return false;
+    } else {
+        s = 0;
+    }
+
+    // Steps 13-14.
+    double milli;
+    if (args.length() >= 7) {
+        if (!ToNumber(cx, args[6], &milli))
+            return false;
+    } else {
+        milli = 0;
+    }
+
+    // Step 15.
+    double yr = y;
+    if (!IsNaN(y)) {
+        double yint = ToInteger(y);
+        if (0 <= yint && yint <= 99)
+            yr = 1900 + yint;
+    }
+
+    // Step 16.
+    args.rval().setDouble(TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))));
     return true;
 }
 
 /*
  * Read and convert decimal digits from s[*i] into *result
  * while *i < limit.
  *
  * Succeed if any digits are converted. Advance *i only
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/Date/UTC-convert-all-arguments.js
@@ -0,0 +1,70 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommonn.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1160356;
+var summary =
+  "Date.UTC 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 args =
+ [
+  [bad],
+
+  [NaN, bad],
+  [Infinity, bad],
+  [1970, bad],
+
+  [1970, NaN, bad],
+  [1970, Infinity, bad],
+  [1970, 4, bad],
+
+  [1970, 4, NaN, bad],
+  [1970, 4, Infinity, bad],
+  [1970, 4, 17, bad],
+
+  [1970, 4, 17, NaN, bad],
+  [1970, 4, 17, Infinity, bad],
+  [1970, 4, 17, 13, bad],
+
+  [1970, 4, 17, 13, NaN, bad],
+  [1970, 4, 17, 13, Infinity, bad],
+  [1970, 4, 17, 13, 37, bad],
+
+  [1970, 4, 17, 13, 37, NaN, bad],
+  [1970, 4, 17, 13, 37, Infinity, bad],
+  [1970, 4, 17, 13, 37, 23, bad],
+ ];
+
+for (var i = 0, len = args.length; i < len; i++)
+  expectThrowTypeError(function() { Date.UTC.apply(null, args[i]); }, i);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("Tests complete");