diff options
-rw-r--r-- | mysql-test/r/variables.result | 7 | ||||
-rw-r--r-- | mysql-test/t/variables.test | 15 | ||||
-rw-r--r-- | sql/mysqld.cc | 7 | ||||
-rw-r--r-- | sql/set_var.cc | 18 | ||||
-rw-r--r-- | sql/set_var.h | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 13 |
7 files changed, 65 insertions, 1 deletions
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 94a7661d327..a297dbfa502 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1026,6 +1026,13 @@ hostname # # Test 'myisam_mmap_size' option is not dynamic SET @@myisam_mmap_size= 500M; ERROR HY000: Variable 'myisam_mmap_size' is a read only variable +# +# Bug #52315: utc_date() crashes when system time > year 2037 +# +SET TIMESTAMP=2*1024*1024*1024; +#Should not crash +SELECT UTC_DATE(); +SET TIMESTAMP=DEFAULT; End of 5.0 tests set join_buffer_size=1; Warnings: diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 7b3ea599b9e..d5929041e8a 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -785,6 +785,21 @@ show variables like 'hostname'; --echo # Test 'myisam_mmap_size' option is not dynamic --error ER_INCORRECT_GLOBAL_LOCAL_VAR SET @@myisam_mmap_size= 500M; + + +--echo # +--echo # Bug #52315: utc_date() crashes when system time > year 2037 +--echo # + +--error 0, ER_UNKNOWN_ERROR +SET TIMESTAMP=2*1024*1024*1024; +--echo #Should not crash +--disable_result_log +SELECT UTC_DATE(); +--enable_result_log +SET TIMESTAMP=DEFAULT; + + --echo End of 5.0 tests # diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3ffc1a21e9c..7598c2a5276 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3233,6 +3233,13 @@ static int init_common_variables(const char *conf_file_name, int argc, max_system_variables.pseudo_thread_id= (ulong)~0; server_start_time= flush_status_time= my_time(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; + } + rpl_filter= new Rpl_filter; binlog_filter= new Rpl_filter; if (!rpl_filter || !binlog_filter) diff --git a/sql/set_var.cc b/sql/set_var.cc index 8f0ad93ba43..241126e1e6f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2718,10 +2718,26 @@ int set_var_collation_client::update(THD *thd) /****************************************************************************/ +bool sys_var_timestamp::check(THD *thd, set_var *var) +{ + time_t 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) + { + my_message(ER_UNKNOWN_ERROR, + "This version of MySQL doesn't support dates later than 2038", + MYF(0)); + return TRUE; + } + return FALSE; +} + + bool sys_var_timestamp::update(THD *thd, set_var *var) { thd->set_time((time_t) var->save_result.ulonglong_value); - return 0; + return FALSE; } diff --git a/sql/set_var.h b/sql/set_var.h index fa747107870..bc94c6b85c4 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -662,6 +662,7 @@ public: Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG) :sys_var(name_arg, NULL, binlog_status_arg) { chain_sys_var(chain); } + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); void set_default(THD *thd, enum_var_type type); bool check_type(enum_var_type type) { return type == OPT_GLOBAL; } diff --git a/sql/sql_class.h b/sql/sql_class.h index bd3cf8bc401..19a433746e4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2029,6 +2029,11 @@ public: start_time= user_time= t; start_utime= utime_after_lock= my_micro_time(); } + /*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); + } void set_time_after_lock() { utime_after_lock= my_micro_time(); } ulonglong current_utime() { return my_micro_time(); } inline ulonglong found_rows(void) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f28f8f1868a..7af263f62c5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -994,6 +994,19 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->enable_slow_log= TRUE; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->set_time(); + if (!thd->is_valid_time()) + { + /* + If the time has got past 2038 we need to shut this server down + We do this by making sure every command is a shutdown and we + have enough privileges to shut the server down + + TODO: remove this when we have full 64 bit my_time_t support + */ + thd->security_ctx->master_access|= SHUTDOWN_ACL; + command= COM_SHUTDOWN; + } + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id= global_query_id; |