Title: [215359] trunk
Revision
215359
Author
utatane....@gmail.com
Date
2017-04-14 00:59:55 -0700 (Fri, 14 Apr 2017)

Log Message

[JSC] Date.parse should accept wider range of representation
https://bugs.webkit.org/show_bug.cgi?id=170720

Reviewed by Darin Adler.

JSTests:

* stress/date-relaxed.js: Added.
(shouldBe):
(throw.new.Error):

Source/WTF:

We would like to relax Date.parse to accept the representation "May 8".
At that time, we choose `2000` as a default year. This is because of
the following reason.

1. According to the V8, this default value is compatible to the old KJS. While current V8 uses 2001,
   SpiderMonkey does not have such a fallback path. So this reason is not big deal.

2. It is a leap year. When using `new Date("Feb 29")`, we assume that people want to save month and day.
   Leap year can save user inputs if they is valid. If we use the current year instead, the current year
   may not be a leap year. In that case, `new Date("Feb 29").getMonth()` becomes 2 (March).

* wtf/DateMath.cpp:
(WTF::parseDateFromNullTerminatedCharacters):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (215358 => 215359)


--- trunk/JSTests/ChangeLog	2017-04-14 06:51:51 UTC (rev 215358)
+++ trunk/JSTests/ChangeLog	2017-04-14 07:59:55 UTC (rev 215359)
@@ -1,3 +1,14 @@
+2017-04-13  Yusuke Suzuki  <utatane....@gmail.com>
+
+        [JSC] Date.parse should accept wider range of representation
+        https://bugs.webkit.org/show_bug.cgi?id=170720
+
+        Reviewed by Darin Adler.
+
+        * stress/date-relaxed.js: Added.
+        (shouldBe):
+        (throw.new.Error):
+
 2017-04-13  Mark Lam  <mark....@apple.com>
 
         Should use flushDirect() when flushing the scopeRegister due to needsScopeRegister().

Added: trunk/JSTests/stress/date-relaxed.js (0 => 215359)


--- trunk/JSTests/stress/date-relaxed.js	                        (rev 0)
+++ trunk/JSTests/stress/date-relaxed.js	2017-04-14 07:59:55 UTC (rev 215359)
@@ -0,0 +1,61 @@
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error(`bad value: ${actual}`);
+}
+
+{
+    let date = new Date("May 8");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 4);
+    shouldBe(date.getDate(), 8);
+}
+{
+    let date = new Date("Feb 29");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 1);
+    shouldBe(date.getDate(), 29);
+}
+{
+    let date = new Date(" May 8 ");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 4);
+    shouldBe(date.getDate(), 8);
+}
+{
+    let date = new Date(" Feb 29 ");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 1);
+    shouldBe(date.getDate(), 29);
+}
+{
+    let date = new Date("May/8");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 4);
+    shouldBe(date.getDate(), 8);
+}
+{
+    let date = new Date("Feb/29");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 1);
+    shouldBe(date.getDate(), 29);
+}
+{
+    let date = new Date("May8");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 4);
+    shouldBe(date.getDate(), 8);
+}
+{
+    let date = new Date("Feb29");
+    shouldBe(date.getFullYear(), 2000);
+    shouldBe(date.getMonth(), 1);
+    shouldBe(date.getDate(), 29);
+}
+
+{
+    let date = new Date("May 8 -1");
+    shouldBe(date.getFullYear(), -1);
+    shouldBe(date.getMonth(), 4);
+    shouldBe(date.getDate(), 8);
+}

Modified: trunk/Source/WTF/ChangeLog (215358 => 215359)


--- trunk/Source/WTF/ChangeLog	2017-04-14 06:51:51 UTC (rev 215358)
+++ trunk/Source/WTF/ChangeLog	2017-04-14 07:59:55 UTC (rev 215359)
@@ -1,3 +1,24 @@
+2017-04-13  Yusuke Suzuki  <utatane....@gmail.com>
+
+        [JSC] Date.parse should accept wider range of representation
+        https://bugs.webkit.org/show_bug.cgi?id=170720
+
+        Reviewed by Darin Adler.
+
+        We would like to relax Date.parse to accept the representation "May 8".
+        At that time, we choose `2000` as a default year. This is because of
+        the following reason.
+
+        1. According to the V8, this default value is compatible to the old KJS. While current V8 uses 2001,
+           SpiderMonkey does not have such a fallback path. So this reason is not big deal.
+
+        2. It is a leap year. When using `new Date("Feb 29")`, we assume that people want to save month and day.
+           Leap year can save user inputs if they is valid. If we use the current year instead, the current year
+           may not be a leap year. In that case, `new Date("Feb 29").getMonth()` becomes 2 (March).
+
+        * wtf/DateMath.cpp:
+        (WTF::parseDateFromNullTerminatedCharacters):
+
 2017-04-13  Dan Bernstein  <m...@apple.com>
 
         WTF installs an extra copy of a header outside /usr/local/include/wtf

Modified: trunk/Source/WTF/wtf/DateMath.cpp (215358 => 215359)


--- trunk/Source/WTF/wtf/DateMath.cpp	2017-04-14 06:51:51 UTC (rev 215358)
+++ trunk/Source/WTF/wtf/DateMath.cpp	2017-04-14 07:59:55 UTC (rev 215359)
@@ -891,13 +891,10 @@
         return std::numeric_limits<double>::quiet_NaN();
     dateString = newPosStr;
 
-    if (!*dateString)
-        return std::numeric_limits<double>::quiet_NaN();
-
     if (day < 0)
         return std::numeric_limits<double>::quiet_NaN();
 
-    int year = 0;
+    std::optional<int> year;
     if (day > 31) {
         // ### where is the boundary and what happens below?
         if (*dateString != '/')
@@ -961,9 +958,11 @@
         return std::numeric_limits<double>::quiet_NaN();
 
     // '99 23:12:40 GMT'
-    if (year <= 0 && *dateString) {
-        if (!parseInt(dateString, &newPosStr, 10, &year))
+    if (*dateString && !year) {
+        int result = 0;
+        if (!parseInt(dateString, &newPosStr, 10, &result))
             return std::numeric_limits<double>::quiet_NaN();
+        year = result;
     }
 
     // Don't fail if the time is missing.
@@ -978,7 +977,7 @@
             if (*newPosStr != ':')
                 return std::numeric_limits<double>::quiet_NaN();
             // There was no year; the number was the hour.
-            year = -1;
+            year = std::nullopt;
         } else {
             // in the normal case (we parsed the year), advance to the next number
             dateString = ++newPosStr;
@@ -1048,9 +1047,11 @@
     }
     
     // The year may be after the time but before the time zone.
-    if (isASCIIDigit(*dateString) && year == -1) {
-        if (!parseInt(dateString, &newPosStr, 10, &year))
+    if (isASCIIDigit(*dateString) && !year) {
+        int result = 0;
+        if (!parseInt(dateString, &newPosStr, 10, &result))
             return std::numeric_limits<double>::quiet_NaN();
+        year = result;
         dateString = newPosStr;
         skipSpacesAndComments(dateString);
     }
@@ -1102,9 +1103,11 @@
 
     skipSpacesAndComments(dateString);
 
-    if (*dateString && year == -1) {
-        if (!parseInt(dateString, &newPosStr, 10, &year))
+    if (*dateString && !year) {
+        int result = 0;
+        if (!parseInt(dateString, &newPosStr, 10, &result))
             return std::numeric_limits<double>::quiet_NaN();
+        year = result;
         dateString = newPosStr;
         skipSpacesAndComments(dateString);
     }
@@ -1114,14 +1117,28 @@
         return std::numeric_limits<double>::quiet_NaN();
 
     // Y2K: Handle 2 digit years.
-    if (year >= 0 && year < 100) {
-        if (year < 50)
-            year += 2000;
-        else
-            year += 1900;
+    if (year) {
+        int yearValue = year.value();
+        if (yearValue >= 0 && yearValue < 100) {
+            if (yearValue < 50)
+                yearValue += 2000;
+            else
+                yearValue += 1900;
+        }
+        year = yearValue;
+    } else {
+        // We select 2000 as default value. This is because of the following reasons.
+        // 1. Year 2000 was used for the initial value of the variable `year`. While it won't be posed to users in WebKit,
+        //    V8 used this 2000 as its default value. (As of April 2017, V8 is using the year 2001 and Spider Monkey is
+        //    not doing this kind of fallback.)
+        // 2. It is a leap year. When using `new Date("Feb 29")`, we assume that people want to save month and day.
+        //    Leap year can save user inputs if they is valid. If we use the current year instead, the current year
+        //    may not be a leap year. In that case, `new Date("Feb 29").getMonth()` becomes 2 (March).
+        year = 2000;
     }
+    ASSERT(year);
     
-    return ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSecond;
+    return ymdhmsToSeconds(year.value(), month + 1, day, hour, minute, second) * msPerSecond;
 }
 
 double parseDateFromNullTerminatedCharacters(const char* dateString)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to