Bug 1500748 - Require standard compliance when a time part exists r=arai
authorKagami Sascha Rosylight <saschanaz@outlook.com>
Sun, 12 May 2019 10:23:14 +0000
changeset 532363 efacc855c35612cec29992fd6149e38db2fd1690
parent 532362 0bcfcc0bbc658890cbb6e218b2f2f06b42a56b16
child 532364 40377335c3b5597fef5a638ea42870039b34d34c
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1500748
milestone68.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 1500748 - Require standard compliance when a time part exists r=arai Differential Revision: https://phabricator.services.mozilla.com/D30761
js/src/jsdate.cpp
js/src/tests/non262/Date/non-iso.js
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -900,28 +900,30 @@ static int DaysInMonth(int year, int mon
  *   ss   = one or two digits of second (00 through 59)
  *   sss  = one or more digits representing a decimal fraction of a second
  *   TZD  = time zone designator (Z or +hh:mm or -hh:mm or missing for local)
  */
 template <typename CharT>
 static bool ParseISOStyleDate(const CharT* s, size_t length,
                               ClippedTime* result) {
   size_t i = 0;
+  size_t pre = 0;
   int tzMul = 1;
   int dateMul = 1;
   size_t year = 1970;
   size_t month = 1;
   size_t day = 1;
   size_t hour = 0;
   size_t min = 0;
   size_t sec = 0;
   double frac = 0;
   bool isLocalTime = false;
   size_t tzHour = 0;
   size_t tzMin = 0;
+  bool isPermissive = false;
 
 #define PEEK(ch) (i < length && s[i] == ch)
 
 #define NEED(ch)                   \
   if (i >= length || s[i] != ch) { \
     return false;                  \
   } else {                         \
     ++i;                           \
@@ -942,18 +944,22 @@ static bool ParseISOStyleDate(const Char
   }
 
 #define NEED_NDIGITS(n, field)                   \
   if (!ParseDigitsN(n, &field, s, &i, length)) { \
     return false;                                \
   }
 
 #define NEED_NDIGITS_OR_LESS(n, field)                 \
+  pre = i;                                             \
   if (!ParseDigitsNOrLess(n, &field, s, &i, length)) { \
     return false;                                      \
+  }                                                    \
+  if (i < pre + (n)) {                                 \
+    isPermissive = true;                               \
   }
 
   if (PEEK('+') || PEEK('-')) {
     if (PEEK('-')) {
       dateMul = -1;
     }
     ++i;
     NEED_NDIGITS(6, year);
@@ -961,17 +967,24 @@ static bool ParseISOStyleDate(const Char
     NEED_NDIGITS(4, year);
   }
   DONE_DATE_UNLESS('-');
   NEED_NDIGITS_OR_LESS(2, month);
   DONE_DATE_UNLESS('-');
   NEED_NDIGITS_OR_LESS(2, day);
 
 done_date:
-  if (PEEK('T') || PEEK(' ')) {
+  if (PEEK('T')) {
+    if (isPermissive) {
+      // Require standard format "[+00]1970-01-01" if a time part marker "T"
+      // exists
+      return false;
+    }
+    i++;
+  } else if (PEEK(' ')) {
     i++;
   } else {
     goto done;
   }
 
   NEED_NDIGITS_OR_LESS(2, hour);
   NEED(':');
   NEED_NDIGITS_OR_LESS(2, min);
--- a/js/src/tests/non262/Date/non-iso.js
+++ b/js/src/tests/non262/Date/non-iso.js
@@ -19,19 +19,19 @@
 assertEq(new Date("1997-03-08 1:1:1.01").getTime(),
          new Date("1997-03-08T01:01:01.01").getTime());
 assertEq(new Date("1997-03-08 11:19:20").getTime(),
          new Date("1997-03-08T11:19:20").getTime());
 assertEq(new Date("1997-3-08 11:19:20").getTime(),
          new Date("1997-03-08T11:19:20").getTime());
 assertEq(new Date("1997-3-8 11:19:20").getTime(),
          new Date("1997-03-08T11:19:20").getTime());
-assertEq(new Date("1997-3-8T11:19:20").getTime(),
+assertEq(new Date("+001997-3-8 11:19:20").getTime(),
          new Date("1997-03-08T11:19:20").getTime());
-assertEq(new Date("1997-03-8T11:19:20").getTime(),
+assertEq(new Date("+001997-03-8 11:19:20").getTime(),
          new Date("1997-03-08T11:19:20").getTime());
 assertEq(new Date("1997-03-08 11:19").getTime(),
          new Date("1997-03-08T11:19").getTime());
 assertEq(new Date("1997-03-08 1:19").getTime(),
          new Date("1997-03-08T1:19").getTime());
 assertEq(new Date("1997-03-08 1:1").getTime(),
          new Date("1997-03-08T1:1").getTime());
 assertEq(new Date("1997-03-08 1:1:01").getTime(),
@@ -43,16 +43,24 @@ assertEq(new Date("1997-03-08 11").getTi
 assertEq(new Date("1997-03-08").getTime(),
          new Date("1997-03-08").getTime());
 assertEq(new Date("1997-03-8").getTime(),
          new Date("1997-03-08").getTime());
 assertEq(new Date("1997-3-8").getTime(),
          new Date("1997-03-08").getTime());
 assertEq(new Date("1997-3-8 ").getTime(),
          new Date("1997-03-08T").getTime()); // Date(NaN)
+assertEq(new Date("1997-3-8T11:19:20").getTime(),
+         new Date(NaN).getTime());
+assertEq(new Date("1997-03-8T11:19:20").getTime(),
+         new Date(NaN).getTime());
+assertEq(new Date("+001997-3-8T11:19:20").getTime(),
+         new Date(NaN).getTime());
+assertEq(new Date("+001997-3-08T11:19:20").getTime(),
+         new Date(NaN).getTime());
 assertEq(new Date("1997-3-8 :00:01").getTime(),
          new Date(NaN).getTime());
 assertEq(new Date("1997-3-8 :00:01").getTime(),
          new Date(NaN).getTime());
 assertEq(new Date("1997-3-8 01::01").getTime(),
          new Date(NaN).getTime());
 
 /******************************************************************************/