Title: [232122] trunk
Revision
232122
Author
[email protected]
Date
2018-05-23 13:02:37 -0700 (Wed, 23 May 2018)

Log Message

Date.parse() doesn't properly handle input outside of ES Spec limits
https://bugs.webkit.org/show_bug.cgi?id=185868

Reviewed by Mark Lam.

JSTests:

New test.

* stress/date-parse-ranges.js: Added.
(shouldBe):
(throw.new.Error):
(shouldBeNaN):

Source/WTF:

Clamped date creation to +/-100,000,000 days relative to midnight at the beginning
of 01 January, 1970 UTC as per ecma262/#sec-time-values-and-time-range and
ecma262/#sec-date-time-string-format.

* wtf/DateMath.cpp:
(WTF::ymdhmsToSeconds):
(WTF::parseES5DateFromNullTerminatedCharacters):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (232121 => 232122)


--- trunk/JSTests/ChangeLog	2018-05-23 19:09:08 UTC (rev 232121)
+++ trunk/JSTests/ChangeLog	2018-05-23 20:02:37 UTC (rev 232122)
@@ -1,3 +1,17 @@
+2018-05-23  Michael Saboff  <[email protected]>
+
+        Date.parse() doesn't properly handle input outside of ES Spec limits
+        https://bugs.webkit.org/show_bug.cgi?id=185868
+
+        Reviewed by Mark Lam.
+
+        New test.
+
+        * stress/date-parse-ranges.js: Added.
+        (shouldBe):
+        (throw.new.Error):
+        (shouldBeNaN):
+
 2018-05-23  Rick Waldron  <[email protected]>
 
         Conversion misspelled "Convertion" in error message string

Added: trunk/JSTests/stress/date-parse-ranges.js (0 => 232122)


--- trunk/JSTests/stress/date-parse-ranges.js	                        (rev 0)
+++ trunk/JSTests/stress/date-parse-ranges.js	2018-05-23 20:02:37 UTC (rev 232122)
@@ -0,0 +1,145 @@
+// This test checks that dates follow the range described in ecma262/#sec-date-time-string-format
+
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error(`bad value: ${actual}`);
+}
+
+function shouldBeNaN(actual)
+{
+    if (!Number.isNaN(actual))
+        throw new Error(`bad value: ${actual}`);
+}
+
+{
+    let dateValue = Date.parse("275760-09-13T00:00:00.000Z");
+    shouldBe(dateValue, 8640000000000000);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), 275760);
+    shouldBe(date.getUTCMonth(), 8);
+    shouldBe(date.getUTCDate(), 13);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 0);
+}
+
+{
+    let dateValue = Date.UTC(275760, 8, 13, 0, 0, 0, 0);
+    shouldBe(dateValue, 8640000000000000);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), 275760);
+    shouldBe(date.getUTCMonth(), 8);
+    shouldBe(date.getUTCDate(), 13);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 0);
+}
+
+{
+    let dateValue = Date.parse("275760-09-12T23:59:59.999Z");
+    shouldBe(dateValue, 8639999999999999);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), 275760);
+    shouldBe(date.getUTCMonth(), 8);
+    shouldBe(date.getUTCDate(), 12);
+    shouldBe(date.getUTCHours(), 23);
+    shouldBe(date.getUTCMinutes(), 59);
+    shouldBe(date.getUTCSeconds(), 59);
+    shouldBe(date.getUTCMilliseconds(), 999);
+}
+
+{
+    let dateValue = Date.UTC(275760, 8, 12, 23, 59, 59, 999);
+    shouldBe(dateValue, 8639999999999999);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), 275760);
+    shouldBe(date.getUTCMonth(), 8);
+    shouldBe(date.getUTCDate(), 12);
+    shouldBe(date.getUTCHours(), 23);
+    shouldBe(date.getUTCMinutes(), 59);
+    shouldBe(date.getUTCSeconds(), 59);
+    shouldBe(date.getUTCMilliseconds(), 999);
+}
+
+{
+    let dateValue = Date.parse("275760-09-13T00:00:00.001Z");
+    shouldBeNaN(dateValue);
+}
+
+{
+    let dateValue = Date.UTC(275760, 8, 13, 0, 0, 0, 1);
+    shouldBeNaN(dateValue);
+}
+
+{
+    let dateValue = Date.parse("-271821-04-20T00:00:00.000Z");
+    shouldBe(dateValue, -8640000000000000);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), -271821);
+    shouldBe(date.getUTCMonth(), 3);
+    shouldBe(date.getUTCDate(), 20);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 0);
+}
+
+{
+    let dateValue = Date.UTC(-271821, 3, 20, 0, 0, 0, 0);
+    shouldBe(dateValue, -8640000000000000);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), -271821);
+    shouldBe(date.getUTCMonth(), 3);
+    shouldBe(date.getUTCDate(), 20);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 0);
+}
+
+{
+    let dateValue = Date.parse("-271821-04-20T00:00:00.001Z");
+    shouldBe(dateValue, -8639999999999999);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), -271821);
+    shouldBe(date.getUTCMonth(), 3);
+    shouldBe(date.getUTCDate(), 20);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 1);
+}
+
+{
+    let dateValue = Date.UTC(-271821, 3, 20, 0, 0, 0, 1);
+    shouldBe(dateValue, -8639999999999999);
+
+    let date = new Date(dateValue);
+    shouldBe(date.getUTCFullYear(), -271821);
+    shouldBe(date.getUTCMonth(), 3);
+    shouldBe(date.getUTCDate(), 20);
+    shouldBe(date.getUTCHours(), 0);
+    shouldBe(date.getUTCMinutes(), 0);
+    shouldBe(date.getUTCSeconds(), 0);
+    shouldBe(date.getUTCMilliseconds(), 1);
+}
+
+{
+    let dateValue = Date.parse("-271821-04-19T23:59:59.999Z");
+    shouldBeNaN(dateValue);
+}
+
+{
+    let dateValue = Date.UTC(-271821, 3, 19, 23, 59, 59, 999);
+    shouldBeNaN(dateValue);
+}

Modified: trunk/Source/WTF/ChangeLog (232121 => 232122)


--- trunk/Source/WTF/ChangeLog	2018-05-23 19:09:08 UTC (rev 232121)
+++ trunk/Source/WTF/ChangeLog	2018-05-23 20:02:37 UTC (rev 232122)
@@ -1,3 +1,18 @@
+2018-05-23  Michael Saboff  <[email protected]>
+
+        Date.parse() doesn't properly handle input outside of ES Spec limits
+        https://bugs.webkit.org/show_bug.cgi?id=185868
+
+        Reviewed by Mark Lam.
+
+        Clamped date creation to +/-100,000,000 days relative to midnight at the beginning
+        of 01 January, 1970 UTC as per ecma262/#sec-time-values-and-time-range and
+        ecma262/#sec-date-time-string-format.
+
+        * wtf/DateMath.cpp:
+        (WTF::ymdhmsToSeconds):
+        (WTF::parseES5DateFromNullTerminatedCharacters):
+
 2018-05-22  Michael Catanzaro  <[email protected]>
 
         Prohibit shrinking the FastBitVector

Modified: trunk/Source/WTF/wtf/DateMath.cpp (232121 => 232122)


--- trunk/Source/WTF/wtf/DateMath.cpp	2018-05-23 19:09:08 UTC (rev 232121)
+++ trunk/Source/WTF/wtf/DateMath.cpp	2018-05-23 20:02:37 UTC (rev 232122)
@@ -557,7 +557,14 @@
     int mday = firstDayOfMonth[isLeapYear(year)][mon - 1];
     double ydays = daysFrom1970ToYear(year);
 
-    return (second + minute * secondsPerMinute + hour * secondsPerHour + (mday + day - 1 + ydays) * secondsPerDay);
+    double dateSeconds = second + minute * secondsPerMinute + hour * secondsPerHour + (mday + day - 1 + ydays) * secondsPerDay;
+
+    // Clamp to EcmaScript standard (ecma262/#sec-time-values-and-time-range) of
+    //  +/- 100,000,000 days from 01 January, 1970.
+    if (dateSeconds < -8640000000000.0 || dateSeconds > 8640000000000.0)
+        return std::numeric_limits<double>::quiet_NaN();
+    
+    return dateSeconds;
 }
 
 // We follow the recommendation of RFC 2822 to consider all
@@ -778,7 +785,7 @@
 
 double parseES5DateFromNullTerminatedCharacters(const char* dateString)
 {
-    // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15
+    // This parses a date of the form defined in ecma262/#sec-date-time-string-format
     // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z).
     // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace).
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to