Revision: 9829
Author: [email protected]
Date: Fri Oct 28 01:45:04 2011
Log: Fix error handling in Date.prototype.toISOString.
This fixes Date.prototyoe.toISOString to throw a RangeError exception
for invalid time values. It also includes a fix to removes the arbitrary
(and completely bogus) range limit on the date value during construction
of a Date object. Note that we still have bogus range limits on the year
and month values.
[email protected]
BUG=v8:1792
TEST=mjsunit/date,test262/15.9.5.43-0-*
Review URL: http://codereview.chromium.org/8392036
http://code.google.com/p/v8/source/detail?r=9829
Modified:
/branches/bleeding_edge/src/date.js
/branches/bleeding_edge/src/macros.py
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/test/mjsunit/date.js
/branches/bleeding_edge/test/test262/test262.status
=======================================
--- /branches/bleeding_edge/src/date.js Mon Sep 19 11:36:47 2011
+++ /branches/bleeding_edge/src/date.js Fri Oct 28 01:45:04 2011
@@ -351,13 +351,12 @@
date = TO_INTEGER_MAP_MINUS_ZERO(date);
if (year < kMinYear || year > kMaxYear ||
- month < kMinMonth || month > kMaxMonth ||
- date < kMinDate || date > kMaxDate) {
+ month < kMinMonth || month > kMaxMonth) {
return $NaN;
}
- // Now we rely on year, month and date being SMIs.
- return %DateMakeDay(year, month, date);
+ // Now we rely on year and month being SMIs.
+ return %DateMakeDay(year, month) + date - 1;
}
@@ -978,9 +977,10 @@
}
+// ECMA 262 - 15.9.5.43
function DateToISOString() {
var t = DATE_VALUE(this);
- if (NUMBER_IS_NAN(t)) return kInvalidDate;
+ if (NUMBER_IS_NAN(t)) throw MakeRangeError("invalid_time_value", []);
var year = this.getUTCFullYear();
var year_string;
if (year >= 0 && year <= 9999) {
=======================================
--- /branches/bleeding_edge/src/macros.py Mon Oct 17 05:44:16 2011
+++ /branches/bleeding_edge/src/macros.py Fri Oct 28 01:45:04 2011
@@ -82,8 +82,6 @@
const kMaxYear = 1000000;
const kMinMonth = -10000000;
const kMaxMonth = 10000000;
-const kMinDate = -100000000;
-const kMaxDate = 100000000;
# Native cache ids.
const STRING_TO_REGEXP_CACHE_ID = 0;
=======================================
--- /branches/bleeding_edge/src/messages.js Wed Oct 26 03:41:52 2011
+++ /branches/bleeding_edge/src/messages.js Fri Oct 28 01:45:04 2011
@@ -198,6 +198,7 @@
// RangeError
"invalid_array_length", ["Invalid array length"],
"stack_overflow", ["Maximum call stack size exceeded"],
+ "invalid_time_value", ["Invalid time value"],
// SyntaxError
"unable_to_parse", ["Parse error"],
"invalid_regexp_flags", ["Invalid flags supplied to RegExp
constructor '", "%0", "'"],
=======================================
--- /branches/bleeding_edge/src/runtime.cc Tue Oct 25 07:14:56 2011
+++ /branches/bleeding_edge/src/runtime.cc Fri Oct 28 01:45:04 2011
@@ -7490,7 +7490,7 @@
}
-static int MakeDay(int year, int month, int day) {
+static int MakeDay(int year, int month) {
static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
@@ -7527,23 +7527,22 @@
year1 / 400 -
base_day;
- if (year % 4 || (year % 100 == 0 && year % 400 != 0)) {
- return day_from_year + day_from_month[month] + day - 1;
+ if ((year % 4 != 0) || (year % 100 == 0 && year % 400 != 0)) {
+ return day_from_year + day_from_month[month];
}
- return day_from_year + day_from_month_leap[month] + day - 1;
+ return day_from_year + day_from_month_leap[month];
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
NoHandleAllocation ha;
- ASSERT(args.length() == 3);
+ ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(year, 0);
CONVERT_SMI_ARG_CHECKED(month, 1);
- CONVERT_SMI_ARG_CHECKED(date, 2);
-
- return Smi::FromInt(MakeDay(year, month, date));
+
+ return Smi::FromInt(MakeDay(year, month));
}
@@ -7772,7 +7771,7 @@
month = kMonthInYear[date];
day = kDayInYear[date];
- ASSERT(MakeDay(year, month, day) == save_date);
+ ASSERT(MakeDay(year, month) + day - 1 == save_date);
}
@@ -7786,7 +7785,7 @@
year = 400 * (date / kDaysIn400Years) - kYearsOffset;
date %= kDaysIn400Years;
- ASSERT(MakeDay(year, 0, 1) + date == save_date);
+ ASSERT(MakeDay(year, 0) + date == save_date);
date--;
int yd1 = date / kDaysIn100Years;
@@ -7809,8 +7808,8 @@
ASSERT(is_leap || (date >= 0));
ASSERT((date < 365) || (is_leap && (date < 366)));
ASSERT(is_leap == ((year % 4 == 0) && (year % 100 || (year % 400 ==
0))));
- ASSERT(is_leap || ((MakeDay(year, 0, 1) + date) == save_date));
- ASSERT(!is_leap || ((MakeDay(year, 0, 1) + date + 1) == save_date));
+ ASSERT(is_leap || ((MakeDay(year, 0) + date) == save_date));
+ ASSERT(!is_leap || ((MakeDay(year, 0) + date + 1) == save_date));
if (is_leap) {
day = kDayInYear[2*365 + 1 + date];
@@ -7820,7 +7819,7 @@
month = kMonthInYear[date];
}
- ASSERT(MakeDay(year, month, day) == save_date);
+ ASSERT(MakeDay(year, month) + day - 1 == save_date);
}
=======================================
--- /branches/bleeding_edge/src/runtime.h Tue Oct 25 07:14:56 2011
+++ /branches/bleeding_edge/src/runtime.h Fri Oct 28 01:45:04 2011
@@ -246,7 +246,7 @@
F(DateLocalTimezone, 1, 1) \
F(DateLocalTimeOffset, 0, 1) \
F(DateDaylightSavingsOffset, 1, 1) \
- F(DateMakeDay, 3, 1) \
+ F(DateMakeDay, 2, 1) \
F(DateYMDFromTime, 2, 1) \
\
/* Numbers */ \
=======================================
--- /branches/bleeding_edge/test/mjsunit/date.js Fri Jul 1 04:41:45 2011
+++ /branches/bleeding_edge/test/mjsunit/date.js Fri Oct 28 01:45:04 2011
@@ -157,7 +157,7 @@
// Test that -0 is treated correctly in MakeDay.
var d = new Date();
assertDoesNotThrow("d.setDate(-0)");
-assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0. -0)");
+assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0, -0)");
assertDoesNotThrow("new Date(0x40000000, 0x40000000, 0x40000000," +
"0x40000000, 0x40000000, 0x40000000, 0x40000000)")
assertDoesNotThrow("new Date(-0x40000001, -0x40000001, -0x40000001," +
@@ -178,7 +178,7 @@
assertTrue(isNaN(Date.UTC(-271821, 3, 19)));
-// Test creation of large date values.
+// Test creation with large date values.
d = new Date(1969, 12, 1, 99999999999);
assertTrue(isNaN(d.getTime()));
d = new Date(1969, 12, 1, -99999999999);
@@ -188,6 +188,17 @@
d = new Date(1969, 12, 1, -Infinity);
assertTrue(isNaN(d.getTime()));
+
+// Test creation with obscure date values.
+var timezoneOffset = new Date().getTimezoneOffset();
+d = new Date(1970, 0, 1 + 100000001, -24, -timezoneOffset);
+assertFalse(isNaN(d.getTime()));
+assertEquals(8640000000000000, d.getTime())
+d = new Date(1970, 0, 1 - 100000001, 24, -timezoneOffset);
+assertFalse(isNaN(d.getTime()));
+assertEquals(-8640000000000000, d.getTime())
+
+
// Parsing ES5 ISO-8601 dates.
// When TZ is omitted, it defaults to 'Z' meaning UTC.
=======================================
--- /branches/bleeding_edge/test/test262/test262.status Thu Oct 27 00:50:40
2011
+++ /branches/bleeding_edge/test/test262/test262.status Fri Oct 28 01:45:04
2011
@@ -131,12 +131,6 @@
##################### DELIBERATE INCOMPATIBILITIES #####################
-# 15.9.5.43-0-9 and 15.9.5.43-0-10. V8 doesn't throw RangeError
-# from Date.prototype.toISOString when string is not a finite number.
-# This is compatible with Firefox and Safari.
-15.9.5.43-0-9: PASS || FAIL
-15.9.5.43-0-10: PASS || FAIL
-
# We deliberately treat arguments to parseInt() with a leading zero as
# octal numbers in order to not break the web.
S15.1.2.2_A5.1_T1: FAIL_OK
@@ -478,24 +472,6 @@
# Bug? Array.prototype.reduceRight - decreasing length of array does not
delete
# non-configurable properties
15.4.4.22-9-b-29: FAIL
-# Bug? Date.prototype.toISOString - RangeError is thrown when value of
date is
-# Date(1970, 0, -99999999, 0, 0, 0, -1), the time zone is UTC(0)
-15.9.5.43-0-8: FAIL
-# Bug? Date.prototype.toISOString - RangeError is not thrown when value of
date
-# is Date(1970, 0, 100000001, 0, 0, 0, -1), the time zone is UTC(0)
-15.9.5.43-0-11: FAIL
-# Bug? Date.prototype.toISOString - RangeError is not thrown when value of
date
-# is Date(1970, 0, 100000001, 0, 0, 0, 0), the time zone is UTC(0)
-15.9.5.43-0-12: FAIL
-# Bug? Date.prototype.toISOString - RangeError is thrown when value of
date is
-# Date(1970, 0, 100000001, 0, 0, 0, 1), the time zone is UTC(0)
-15.9.5.43-0-13: FAIL
-# Bug? Date.prototype.toISOString - when value of year is -Infinity
-# Date.prototype.toISOString throw the RangeError
-15.9.5.43-0-14: FAIL
-# Bug? Date.prototype.toISOString - value of year is Infinity
-# Date.prototype.toISOString throw the RangeError
-15.9.5.43-0-15: FAIL
############################ SKIPPED TESTS #############################
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev