From 7e292b9a9a52829bd29bd09f0cfcac8b269d4373 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.blaudden" <> Date: Fri, 23 Feb 2007 17:33:11 +0100 Subject: [PATCH 1/2] Bug#26536 func_time failure on vm-win2003-64-b, occurs every time - Avoid overflow in sec_since_epoch by shifting the time back 2 days for times close to the maximum range of my_time_t - Improve comment about why we need my_time_t - Patch will also fix timezone2.test --- include/my_time.h | 8 +++++++- sql/tztime.cc | 23 ++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/my_time.h b/include/my_time.h index 14726d3a01d..3c8f4274409 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -30,7 +30,13 @@ extern uchar days_in_month[]; /* Portable time_t replacement. - Should be signed and hold seconds for 1902-2038 range. + Should be signed and hold seconds for 1902 -- 2038-01-19 range + i.e at least a 32bit variable + + Using the system built in time_t is not an option as + we rely on the above requirements in the time functions + + For example QNX has an unsigned time_t type */ typedef long my_time_t; diff --git a/sql/tztime.cc b/sql/tztime.cc index 91bd4471463..ac1fa4ddff8 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -780,6 +780,8 @@ gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp) static my_time_t sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) { + /* Guard against my_time_t overflow(on system with 32 bit my_time_t) */ + DBUG_ASSERT(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17)); #ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES /* It turns out that only whenever month is normalized or unnormalized @@ -948,12 +950,12 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp, */ if (shift) { - if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift*86400L + + if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY + sp->revtis[i].rt_offset - saved_seconds)) { DBUG_RETURN(0); /* my_time_t overflow */ } - local_t+= shift*86400L; + local_t+= shift * SECS_PER_DAY; } if (sp->revtis[i].rt_type) @@ -1341,6 +1343,7 @@ my_time_t Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const { my_time_t local_t; + int shift= 0; /* Check timestamp range.we have to do this as calling function relies on @@ -1349,10 +1352,24 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const if (!validate_timestamp_range(t)) return 0; - local_t= sec_since_epoch(t->year, t->month, t->day, + /* + Do a temporary shift of the boundary dates to avoid + overflow of my_time_t if the time value is near it's + maximum range + */ + if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4) + shift= 2; + + local_t= sec_since_epoch(t->year, t->month, (t->day - shift), t->hour, t->minute, t->second) - offset; + if (shift) + { + /* Add back the shifted time */ + local_t+= shift * SECS_PER_DAY; + } + if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE) return local_t; From cb8cbe0033c201c191f68bc99afba794fb329a3d Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.blaudden" <> Date: Fri, 23 Feb 2007 17:59:07 +0100 Subject: [PATCH 2/2] Bug#26536 func_time failure on vm-win2003-64-b, occurs every time - Fixes for 5.1 - Always use long for my_time_t --- include/my_time.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/include/my_time.h b/include/my_time.h index 88abe02ac08..d96c5822069 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -38,13 +38,7 @@ extern uchar days_in_month[]; For example QNX has an unsigned time_t type */ -#if defined(_WIN64) || defined(WIN64) -/* on Win64 long is still 4 bytes (not 8!) */ -typedef LONG64 my_time_t; -#else -typedef time_t my_time_t; - -#endif +typedef long my_time_t; #define MY_TIME_T_MAX LONG_MAX #define MY_TIME_T_MIN LONG_MIN