summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-03 01:24:01 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-03 01:24:01 +0000
commit1e031a19d6c759a0bbb21cdcb26f099d009d8924 (patch)
tree99b79f5b3fc301be050c65b4bb8ccbaf7adc37b9 /base
parentdbf476de0ef1cdcc11c5f2d689b8755809a857fb (diff)
downloadchromium_src-1e031a19d6c759a0bbb21cdcb26f099d009d8924.zip
chromium_src-1e031a19d6c759a0bbb21cdcb26f099d009d8924.tar.gz
chromium_src-1e031a19d6c759a0bbb21cdcb26f099d009d8924.tar.bz2
Avoid a crash in mktime() when Visual C++ 2005 is
used and the input date is in year 3001. R=eroman BUG=4387 Review URL: http://codereview.chromium.org/28340 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10768 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/pr_time_unittest.cc35
-rw-r--r--base/third_party/nspr/prtime.cc36
2 files changed, 65 insertions, 6 deletions
diff --git a/base/pr_time_unittest.cc b/base/pr_time_unittest.cc
index 3b096a2..2ebc724 100644
--- a/base/pr_time_unittest.cc
+++ b/base/pr_time_unittest.cc
@@ -136,7 +136,7 @@ TEST_F(PRTimeTest, ParseTimeTest9) {
// This tests the Time::FromString wrapper over PR_ParseTimeString
TEST_F(PRTimeTest, ParseTimeTest10) {
Time parsed_time;
- bool result = Time::FromString(L"15/10/07 12:45",&parsed_time);
+ bool result = Time::FromString(L"15/10/07 12:45", &parsed_time);
EXPECT_EQ(true, result);
time_t computed_time = parsed_time.ToTimeT();
@@ -172,7 +172,7 @@ TEST_F(PRTimeTest, ParseTimeTestEpoch0) {
TEST_F(PRTimeTest, ParseTimeTestEpoch1) {
Time parsed_time;
-
+
// time_t == 1 second after epoch == 1
EXPECT_EQ(true, Time::FromString(L"Thu Jan 01 01:00:01 +0100 1970",
&parsed_time));
@@ -184,7 +184,7 @@ TEST_F(PRTimeTest, ParseTimeTestEpoch1) {
TEST_F(PRTimeTest, ParseTimeTestEpoch2) {
Time parsed_time;
-
+
// time_t == 2 seconds after epoch == 2
EXPECT_EQ(true, Time::FromString(L"Thu Jan 01 01:00:02 +0100 1970",
&parsed_time));
@@ -238,4 +238,33 @@ TEST_F(PRTimeTest, ParseTimeTestEmpty) {
EXPECT_FALSE(Time::FromString(L"", &parsed_time));
}
+// This test should not crash when compiled with Visual C++ 2005 (see
+// http://crbug.com/4387).
+TEST_F(PRTimeTest, ParseTimeTestOutOfRange) {
+ PRTime parsed_time = 0;
+ // Note the lack of timezone in the time string. The year has to be 3001.
+ // The date has to be after 23:59:59, December 31, 3000, US Pacific Time, so
+ // we use January 2, 3001 to make sure it's after the magic maximum in any
+ // timezone.
+ PRStatus result = PR_ParseTimeString("Sun Jan 2 00:00:00 3001",
+ PR_FALSE, &parsed_time);
+ EXPECT_EQ(PR_SUCCESS, result);
+}
+
+TEST_F(PRTimeTest, ParseTimeTestNotNormalized1) {
+ PRTime parsed_time = 0;
+ PRStatus result = PR_ParseTimeString("Mon Oct 15 12:44:60 PDT 2007",
+ PR_FALSE, &parsed_time);
+ EXPECT_EQ(PR_SUCCESS, result);
+ EXPECT_EQ(comparison_time_pdt, parsed_time);
+}
+
+TEST_F(PRTimeTest, ParseTimeTestNotNormalized2) {
+ PRTime parsed_time = 0;
+ PRStatus result = PR_ParseTimeString("Sun Oct 14 36:45 PDT 2007",
+ PR_FALSE, &parsed_time);
+ EXPECT_EQ(PR_SUCCESS, result);
+ EXPECT_EQ(comparison_time_pdt, parsed_time);
+}
+
} // namespace
diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
index cff5048..733db58 100644
--- a/base/third_party/nspr/prtime.cc
+++ b/base/third_party/nspr/prtime.cc
@@ -41,7 +41,7 @@
*
* NSPR date and time functions
*
- * CVS revision 3.36
+ * CVS revision 3.37
*/
/*
@@ -71,6 +71,7 @@
#elif defined(OS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#endif
+#include <errno.h> /* for EINVAL */
#include <time.h>
/* Implements the Unix localtime_r() function for windows */
@@ -1092,6 +1093,12 @@ PR_ParseTimeString(
result->tm_year = year;
if (dotw != TT_UNKNOWN)
result->tm_wday = (((int)dotw) - ((int)TT_SUN));
+ /*
+ * Mainly to compute wday and yday, but normalized time is also required
+ * by the check below that works around a Visual C++ 2005 mktime problem.
+ */
+ PR_NormalizeTime(result, PR_GMTParameters);
+ /* The remaining work is to set the gmt and dst offsets in tm_params. */
if (zone == TT_UNKNOWN && default_to_gmt)
{
@@ -1141,7 +1148,32 @@ PR_ParseTimeString(
date you are handing it is in daylight savings mode or not;
and if you're wrong, it will "fix" it for you. */
localTime.tm_isdst = -1;
+
+#if _MSC_VER >= 1400 /* 1400 = Visual C++ 2005 (8.0) */
+ /*
+ * mktime will return (time_t) -1 if the input is a date
+ * after 23:59:59, December 31, 3000, US Pacific Time (not
+ * UTC as documented):
+ * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx
+ * But if the year is 3001, mktime also invokes the invalid
+ * parameter handler, causing the application to crash. This
+ * problem has been reported in
+ * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036.
+ * We avoid this crash by not calling mktime if the date is
+ * out of range. To use a simple test that works in any time
+ * zone, we consider year 3000 out of range as well. (See
+ * bug 480740.)
+ */
+ if (result->tm_year >= 3000) {
+ /* Emulate what mktime would have done. */
+ errno = EINVAL;
+ secs = (time_t) -1;
+ } else {
+ secs = mktime(&localTime);
+ }
+#else
secs = mktime(&localTime);
+#endif
if (secs != (time_t) -1)
{
PRTime usecs64;
@@ -1163,8 +1195,6 @@ PR_ParseTimeString(
+ 1440 * (localTime.tm_mday - 2);
}
- /* mainly to compute wday and yday */
- PR_NormalizeTime(result, PR_GMTParameters);
result->tm_params.tp_gmt_offset = zone_offset * 60;
result->tm_params.tp_dst_offset = dst_offset * 60;