- 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)