From 0e44faf27ff243f8e8c1432568eef21964ad326c Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 28 Jun 2013 12:00:25 +0400 Subject: [PATCH] MDEV-4634 Crash in CONVERT_TZ Item_func_min_max::get_date() did not check the returned value against the fuzzy_date flags, so it could return a bad value to the caller that expects a good date (e.h. CONVERT_TZ). modified: mysql-test/r/type_date.result mysql-test/r/type_datetime.result mysql-test/r/type_time.result mysql-test/t/type_date.test mysql-test/t/type_datetime.test mysql-test/t/type_time.test sql/item_func.cc sql/item_timefunc.cc sql/mysql_priv.h sql/time.cc --- mysql-test/r/type_date.result | 11 +++++++++++ mysql-test/r/type_datetime.result | 8 ++++++++ mysql-test/r/type_time.result | 11 +++++++++++ mysql-test/t/type_date.test | 8 ++++++++ mysql-test/t/type_datetime.test | 5 +++++ mysql-test/t/type_time.test | 8 ++++++++ sql/item_func.cc | 6 ++++++ sql/item_timefunc.cc | 12 ++---------- sql/mysql_priv.h | 2 ++ sql/time.cc | 16 ++++++++++++++++ 10 files changed, 77 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 8f9e692d3e0..ca87f430c5d 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -298,3 +298,14 @@ insert t1 values ('2010-10-10 15:foobar'); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 drop table t1; +# +# MDEV-4634 Crash in CONVERT_TZ +# +SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5'); +CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5') +NULL +Warnings: +Warning 1292 Incorrect datetime value: '2022-00-00 00:00:00' +# +# End of 5.3 tests +# diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index e32ee96cc82..b835eacac95 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -681,4 +681,12 @@ c a b 1 1 0000-00-00 3 NULL NULL drop table t1,t2; +# +# MDEV-4634 Crash in CONVERT_TZ +# +SELECT CONVERT_TZ(GREATEST(TIMESTAMP('2021-00-00'),TIMESTAMP('2022-00-00')),'+00:00','+7:5'); +CONVERT_TZ(GREATEST(TIMESTAMP('2021-00-00'),TIMESTAMP('2022-00-00')),'+00:00','+7:5') +NULL +Warnings: +Warning 1292 Incorrect datetime value: '2022-00-00 00:00:00' End of 5.3 tests diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index f2464465d60..5a047f32062 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -173,3 +173,14 @@ select f1, f1 = '2010-10-11 23:38:57' from t1; f1 f1 = '2010-10-11 23:38:57' 23:38:57 0 drop table t1; +# +# MDEV-4634 Crash in CONVERT_TZ +# +SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5'); +CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5') +NULL +Warnings: +Warning 1292 Incorrect datetime value: '0000-00-00 00:00:00' +# +# End of 5.3 tests +# diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 76da6402154..57b545f004b 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -282,3 +282,11 @@ create table t1 (f1 date, key (f1)); insert t1 values ('2010-10-10 15:foobar'); drop table t1; +--echo # +--echo # MDEV-4634 Crash in CONVERT_TZ +--echo # +SELECT CONVERT_TZ(GREATEST(DATE('2021-00-00'),DATE('2022-00-00')),'+00:00','+7:5'); + +--echo # +--echo # End of 5.3 tests +--echo # diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 77ce606697b..87f74530bb3 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -486,5 +486,10 @@ select * from t2 left join t1 on t1.a=t2.c where t1.b is null; drop table t1,t2; +--echo # +--echo # MDEV-4634 Crash in CONVERT_TZ +--echo # +SELECT CONVERT_TZ(GREATEST(TIMESTAMP('2021-00-00'),TIMESTAMP('2022-00-00')),'+00:00','+7:5'); + --echo End of 5.3 tests diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index a456f2b9eea..26d77ad378e 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -123,3 +123,11 @@ insert into t1 values ('23:38:57'); select f1, f1 = '2010-10-11 23:38:57' from t1; drop table t1; +--echo # +--echo # MDEV-4634 Crash in CONVERT_TZ +--echo # +SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5'); + +--echo # +--echo # End of 5.3 tests +--echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d99ceff0d3..ccbdabe0a90 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2469,6 +2469,12 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, uint fuzzy_date) min_max= res; } unpack_time(min_max, ltime); + + if (!(fuzzy_date & TIME_TIME_ONLY) && + ((null_value= check_date_with_warn(ltime, fuzzy_date, + MYSQL_TIMESTAMP_ERROR)))) + return true; + if (compare_as_dates->field_type() == MYSQL_TYPE_DATE) { ltime->time_type= MYSQL_TIMESTAMP_DATE; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index f2e604da4f1..e044441b5d1 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2306,16 +2306,8 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 1; ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; - - int unused; - if (check_date(ltime, fuzzy_date, &unused)) - { - Lazy_string_time str(ltime); - make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_DATE, 0); - return (null_value= 1); - } - return (null_value= 0); + return (null_value= check_date_with_warn(ltime, fuzzy_date, + MYSQL_TIMESTAMP_DATE)); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3acede90d99..1bf5816430c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2568,6 +2568,8 @@ check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut) { return check_date(ltime, non_zero_date(ltime), flags, was_cut); } +bool check_date_with_warn(const MYSQL_TIME *ltime, uint fuzzy_date, + timestamp_type ts_type); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, diff --git a/sql/time.cc b/sql/time.cc index 3b1613282fb..61afeab4787 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -213,6 +213,22 @@ ulong convert_month_to_period(ulong month) } +bool +check_date_with_warn(const MYSQL_TIME *ltime, uint fuzzy_date, + timestamp_type ts_type) +{ + int dummy_warnings; + if (check_date(ltime, fuzzy_date, &dummy_warnings)) + { + Lazy_string_time str(ltime); + make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + &str, MYSQL_TIMESTAMP_ERROR, 0); + return true; + } + return false; +} + + /* Convert a timestamp string to a MYSQL_TIME value and produce a warning if string was truncated during conversion.