diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c index 3387c7184..280a94c4b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c @@ -74,6 +74,9 @@ ecma_date_day_from_time (ecma_number_t time) /**< time value */ static int32_t ecma_date_day_from_year (int32_t year) /**< year value */ { + JERRY_ASSERT (fabs (365.0 * (year - 1970) + ((year - 1969) / 4.0) - ((year - 1901) / 100.0) + ((year - 1601) / 400.0)) + < INT32_MAX); + if (JERRY_LIKELY (year >= 1970)) { return (int32_t) (365 * (year - 1970) + ((year - 1969) / 4) - ((year - 1901) / 100) + ((year - 1601) / 400)); @@ -420,19 +423,23 @@ ecma_date_make_day (ecma_number_t year, /**< year value */ ecma_number_t date) /**< date value */ { /* 1. */ - if (!ecma_number_is_finite (year) || !ecma_number_is_finite (month) || !ecma_number_is_finite (date) - || fabs (year) > INT32_MAX) + if (!ecma_number_is_finite (year) || !ecma_number_is_finite (month) || !ecma_number_is_finite (date)) { return ecma_number_make_nan (); } /* 2., 3., 4. */ - int32_t y = (int32_t) (year); ecma_number_t m = ecma_number_trunc (month); ecma_number_t dt = ecma_number_trunc (date); /* 5. */ - int32_t ym = y + (int32_t) (floor (m / 12)); + year += (floor (m / 12)); + if (fabs (year) > ECMA_DATE_YEAR_LIMIT) + { + return ecma_number_make_nan (); + } + + int32_t int_year = (int32_t) year; /* 6. */ int32_t mn = (int32_t) fmod (m, 12); @@ -443,7 +450,8 @@ ecma_date_make_day (ecma_number_t year, /**< year value */ } /* 7. */ - ecma_number_t days = (ecma_date_day_from_year (ym) + first_day_in_month[ecma_date_in_leap_year (ym)][mn] + (dt - 1)); + ecma_number_t days = + (ecma_date_day_from_year (int_year) + first_day_in_month[ecma_date_in_leap_year (int_year)][mn] + (dt - 1)); return days * ECMA_DATE_MS_PER_DAY; } /* ecma_date_make_day */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 98615f644..db90bc93a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -157,6 +157,8 @@ bool ecma_builtin_is_regexp_exec (ecma_extended_object_t *obj_p); #define ECMA_DATE_DAYS_IN_LEAP_YEAR (366) +#define ECMA_DATE_YEAR_LIMIT (275800) + /** * This gives a range of 8,640,000,000,000,000 milliseconds * to either side of 01 January, 1970 UTC. diff --git a/tests/jerry/date-getters.js b/tests/jerry/date-getters.js index e32e7e694..e6b9d84c5 100644 --- a/tests/jerry/date-getters.js +++ b/tests/jerry/date-getters.js @@ -104,3 +104,17 @@ assert (new Date(-1, -1, -1, -1, -1).getHours() === 22); assert (new Date(-1, -1, -1, -1, -1, -1).getMinutes() === 58); assert (new Date(-1, -1, -1, -1, -1, -1, -1).getSeconds() === 58); assert (new Date(-1, -1, -1, -1, -1, -1, -1, -1).getMilliseconds() === 999); + +/* 6. test case */ +assert (isNaN(new Date(20000000, 0).getFullYear())); +assert (new Date(0, 0).getFullYear() === 1900); +assert (new Date(1.2, 0).getFullYear() === 1901); +assert((new Date(8640000000000000).getFullYear()) == 275760); +assert(isNaN(new Date(8640000000000001).getFullYear())); +assert((new Date(-271821, 3, 21).getFullYear()) == -271821); +assert(isNaN(new Date(1970, 0, -100000000).getFullYear())); +assert(new Date(1970, 0, -100000000 + 1).getFullYear() == -271821); +assert(isNaN(new Date(1970, 0, 100000000 + 2).getFullYear())); +assert(new Date(1970, 0, 100000000).getFullYear() == 275760); +assert(isNaN(new Date(4294967295, -51536298411).getFullYear())); +assert((new Date(4294967295, -51536300000).getFullYear()) == 275628); diff --git a/tests/jerry/date-parse.js b/tests/jerry/date-parse.js index 807d5a9dd..d5488eb09 100644 --- a/tests/jerry/date-parse.js +++ b/tests/jerry/date-parse.js @@ -181,3 +181,12 @@ assert (isNaN(Date.parse("Sat, 13 Sep 275760 00:00:01 GMT"))) // 864000000000100 // Non standard date formats assert (Date.parse("2000/01/01 12:12Z") == 946728720000) assert (Date.parse("1991-07-13 16:04Z") == 679421040000) + +assert(Date.parse('Tue, 13 Sep 275760 00:00:00 GMT') == 8640000000000000); +assert(isNaN(Date.parse('Tue, 14 Sep 275760 00:00:00 GMT'))); +assert(Date.parse("Tue, 20 Apr -271821 00:00:00 GMT") == -8640000000000000); +assert(isNaN(Date.parse("Tue, 19 Apr -271821 00:00:00 GMT"))); +assert(Date.parse('9999') == 253370764800000); +assert(isNaN(Date.parse('10000'))); +assert(Date.parse('-100000') == -3217862419200000); +assert(isNaN(Date.parse('-99999'))); diff --git a/tests/jerry/date-setters.js b/tests/jerry/date-setters.js index f712e11eb..c783ebdcf 100644 --- a/tests/jerry/date-setters.js +++ b/tests/jerry/date-setters.js @@ -241,3 +241,22 @@ assert (isNaN (d.setMonth())); assert (isNaN (d.setUTCMonth())); assert (isNaN (d.setFullYear())); assert (isNaN (d.setUTCFullYear())); + +var date = new Date('1975-08-19'); +var date2 = new Date('1975-08-19'); +var date3 = new Date('1975-08-19'); +var date4 = new Date('1975-08-19'); +var date5 = new Date('1975-08-19'); +var date6 = new Date('1975-08-19'); +date.setFullYear(275760, 8, 13); +date2.setFullYear(275760, 8, 14); +date3.setFullYear(-271820, 6570968, 13); +date4.setFullYear(-271820, 6570968, 14); +date5.setFullYear(-271821); +date6.setFullYear(-271822); +assert(date.getFullYear() == 275760); +assert(isNaN(date2.getFullYear())); +assert(date3.getFullYear() == 275760); +assert(isNaN(date4.getFullYear())); +assert(date5.getFullYear() == -271821); +assert(isNaN(date6.getFullYear()));