List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:February 2 2011 4:51pm
Subject:bzr commit into mysql-5.0 branch (Georgi.Kodinov:2899) Bug#52315 Bug#55755
View as plain text  
#At file:///Users/kgeorge/mysql/work/B55755-5.0/ based on revid:ramil@stripped

 2899 Georgi Kodinov	2011-02-02
      Fixes for Bug #55755 and Bug #52315 part 2
      
      Bug #55755 : Date STD variable signness breaks server on FreeBSD and OpenBSD
      
      * Added a check to configure on the size of time_t
      * Created a macro to check for a valid time_t that is safe to use with datetime 
        functions and store in TIMESTAMP columns.
      * Used the macro consistently instead of the ad-hoc checks introduced by 52315
      * Fixed compliation warnings on platforms where the size of time_t is smaller than
        the size of a long (e.g. OpenBSD 4.8 64 amd64).
      
      Bug #52315: utc_date() crashes when system time > year 2037
      
      * Added a correct check for the timestamp range instead of just variable size check to
      SET TIMESTAMP.
      * Added overflow checking before converting to time_t. 
      * Using a correct localized error message in this case instead of the generic error.
      * Added a test suite.
      * fixed the checks so that they check for unsigned time_t as well. Used the checks 
        consistently across the source code.
      * fixed the original test case to expect the new error code.

    modified:
      configure.in
      include/config-win.h
      include/my_time.h
      mysql-test/r/func_time.result
      mysql-test/t/func_time.test
      mysql-test/t/variables.test
      sql-common/my_time.c
      sql/mysqld.cc
      sql/set_var.cc
      sql/sql_class.h
=== modified file 'configure.in'
--- a/configure.in	2011-01-13 08:57:19 +0000
+++ b/configure.in	2011-02-02 16:51:35 +0000
@@ -1956,6 +1956,15 @@ dnl
 
 MYSQL_CHECK_TIME_T
 
+dnl
+dnl check size of time_t
+dnl
+
+AC_CHECK_SIZEOF(time_t, 8)
+if test "$ac_cv_sizeof_time_t" -eq 0
+then
+  AC_MSG_ERROR("MySQL needs a time_t type.")
+fi
 
 # do we need #pragma interface/#pragma implementation ?
 # yes if it's gcc 2.x, and not icc pretending to be gcc, and not cygwin

=== modified file 'include/config-win.h'
--- a/include/config-win.h	2009-07-31 19:22:02 +0000
+++ b/include/config-win.h	2011-02-02 16:51:35 +0000
@@ -167,6 +167,11 @@ typedef uint rf_SetTimer;
 #define SIZEOF_LONG		4
 #define SIZEOF_LONG_LONG	8
 #define SIZEOF_OFF_T		8
+/*
+  The size of time_t depends on the compiler.
+  But it's 8 for all the supported VC versions.
+*/
+#define SIZEOF_TIME_T		8
 #ifdef _WIN64
 #define SIZEOF_CHARP		8
 #else

=== modified file 'include/my_time.h'
--- a/include/my_time.h	2008-04-03 15:32:00 +0000
+++ b/include/my_time.h	2011-02-02 16:51:35 +0000
@@ -53,6 +53,19 @@ typedef long my_time_t;
 
 #define YY_PART_YEAR	   70
 
+/*
+  check for valid times only if the range of time_t is greater than
+  the range of my_time_t
+*/
+#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
+# define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
+    ((x) <= TIMESTAMP_MAX_VALUE && \
+     (x) >= TIMESTAMP_MIN_VALUE)
+#else
+# define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
+    ((x) >= TIMESTAMP_MIN_VALUE)
+#endif
+
 /* Flags to str_to_datetime */
 #define TIME_FUZZY_DATE		1
 #define TIME_DATETIME_ONLY	2

=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result	2008-12-23 14:08:04 +0000
+++ b/mysql-test/r/func_time.result	2011-02-02 16:51:35 +0000
@@ -1323,4 +1323,21 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
+#
+# Bug #52315 part 2 : utc_date() crashes when system time > year 2037
+#
+SET TIMESTAMP=-147490000;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483648;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483646;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483647;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=0;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=-1;
+SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=1;
+SELECT UTC_TIMESTAMP();
 End of 5.0 tests

=== modified file 'mysql-test/t/func_time.test'
--- a/mysql-test/t/func_time.test	2008-12-23 14:08:04 +0000
+++ b/mysql-test/t/func_time.test	2011-02-02 16:51:35 +0000
@@ -838,4 +838,23 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 --error ER_PARSE_ERROR
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 
+
+--echo #
+--echo # Bug #52315 part 2 : utc_date() crashes when system time > year 2037
+--echo #
+
+--disable_result_log
+--error ER_WRONG_VALUE_FOR_VAR
+SET TIMESTAMP=-147490000; SELECT UTC_TIMESTAMP();
+--error ER_WRONG_VALUE_FOR_VAR
+SET TIMESTAMP=2147483648; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483646; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=2147483647; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=0; SELECT UTC_TIMESTAMP();
+--error ER_WRONG_VALUE_FOR_VAR
+SET TIMESTAMP=-1; SELECT UTC_TIMESTAMP();
+SET TIMESTAMP=1; SELECT UTC_TIMESTAMP();
+--enable_result_log
+
+
 --echo End of 5.0 tests

=== modified file 'mysql-test/t/variables.test'
--- a/mysql-test/t/variables.test	2010-06-04 13:21:19 +0000
+++ b/mysql-test/t/variables.test	2011-02-02 16:51:35 +0000
@@ -776,7 +776,7 @@ SET @@myisam_mmap_size= 500M;
 --echo # Bug #52315: utc_date() crashes when system time > year 2037
 --echo #
 
---error 0, ER_UNKNOWN_ERROR
+--error 0, ER_WRONG_VALUE_FOR_VAR
 SET TIMESTAMP=2*1024*1024*1024;
 --echo #Should not crash
 --disable_result_log

=== modified file 'sql-common/my_time.c'
--- a/sql-common/my_time.c	2009-09-17 15:10:30 +0000
+++ b/sql-common/my_time.c	2011-02-02 16:51:35 +0000
@@ -985,7 +985,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_sr
     with unsigned time_t tmp+= shift*86400L might result in a number,
     larger then TIMESTAMP_MAX_VALUE, so another check will work.
   */
-  if ((tmp < TIMESTAMP_MIN_VALUE) || (tmp > TIMESTAMP_MAX_VALUE))
+  if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp))
     tmp= 0;
 
   return (my_time_t) tmp;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-12-28 18:57:23 +0000
+++ b/sql/mysqld.cc	2011-02-02 16:51:35 +0000
@@ -2836,13 +2836,6 @@ static int init_common_variables(const c
   max_system_variables.pseudo_thread_id= (ulong)~0;
   server_start_time= flush_status_time= time((time_t*) 0);
   
-  /* TODO: remove this when my_time_t is 64 bit compatible */
-  if (server_start_time >= (time_t) MY_TIME_T_MAX)
-  {
-    sql_print_error("This MySQL server doesn't support dates later then 2038");
-    return 1;
-  }
-
   if (init_thread_environment())
     return 1;
   mysql_init_variables();
@@ -2882,6 +2875,13 @@ static int init_common_variables(const c
   mysql_slow_log.init_pthread_objects();
   mysql_bin_log.init_pthread_objects();
 
+  /* TODO: remove this when my_time_t is 64 bit compatible */
+  if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
+  {
+    sql_print_error("This MySQL server doesn't support dates later then 2038");
+    return 1;
+  }
+
   if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
   {
     strmake(glob_hostname, STRING_WITH_LEN("localhost"));

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2010-12-28 18:57:23 +0000
+++ b/sql/set_var.cc	2011-02-02 16:51:35 +0000
@@ -2714,14 +2714,14 @@ int set_var_collation_client::update(THD
 
 bool sys_var_timestamp::check(THD *thd, set_var *var)
 {
-  time_t val;
+  longlong val;
   var->save_result.ulonglong_value= var->value->val_int();
-  val= (time_t) var->save_result.ulonglong_value;
-  if (val < (time_t) MY_TIME_T_MIN || val > (time_t) MY_TIME_T_MAX)
+  val= (longlong) var->save_result.ulonglong_value;
+  if (val != 0 &&          // this is how you set the default value
+      (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE))
   {
-    my_message(ER_UNKNOWN_ERROR, 
-               "This version of MySQL doesn't support dates later than 2038",
-               MYF(0));
+    char buf[64];
+    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", llstr(val, buf));
     return TRUE;
   }
   return FALSE;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-12-28 18:57:23 +0000
+++ b/sql/sql_class.h	2011-02-02 16:51:35 +0000
@@ -1710,7 +1710,7 @@ public:
   /*TODO: this will be obsolete when we have support for 64 bit my_time_t */
   inline bool	is_valid_time() 
   { 
-    return (start_time < (time_t) MY_TIME_T_MAX); 
+    return (IS_TIME_T_VALID_FOR_TIMESTAMP(start_time));
   }
   inline void	insert_id(ulonglong id_arg)
   {


Attachment: [text/bzr-bundle] bzr/georgi.kodinov@oracle.com-20110202165135-8hieawdkp931quj0.bundle
Thread
bzr commit into mysql-5.0 branch (Georgi.Kodinov:2899) Bug#52315 Bug#55755Georgi Kodinov2 Feb