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

Reply via email to