diff options
-rw-r--r-- | mysql-test/r/func_time.result | 10 | ||||
-rw-r--r-- | mysql-test/r/strict.result | 8 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 8 | ||||
-rw-r--r-- | mysql-test/t/strict.test | 10 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 10 | ||||
-rw-r--r-- | sql/sql_time.h | 12 |
6 files changed, 43 insertions, 15 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 38a547843ad..67844eddef2 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1936,3 +1936,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12')); 1 SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12')); 1 +# +# MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y')) +# +SET TIME_ZONE='+02:00'; +SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y')); +UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y')) +NULL +Warnings: +Warning 1411 Incorrect datetime value: '2020' for function str_to_date +SET TIME_ZONE=DEFAULT; diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index b1e4cb669ed..da3c658b5a4 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -206,7 +206,9 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); -ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date +Warnings: +Note 1265 Data truncated for column 'col1' at row 1 +INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -221,8 +223,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date -INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); -ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -238,7 +238,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_da INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); -ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 109734c3316..1a7cd42054b 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1184,3 +1184,11 @@ SELECT 1 FROM DUAL WHERE DAYOFMONTH(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE HOUR(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12')); + + +--echo # +--echo # MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y')) +--echo # +SET TIME_ZONE='+02:00'; +SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y')); +SET TIME_ZONE=DEFAULT; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index f6080de6c2c..c429e9cfe5b 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -188,13 +188,15 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); +# Zero year is not a problem for DATE/DATETIME +INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); + ## Test INSERT with STR_TO_DATE into DATE # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> --error 1411 -INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); ---error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -214,8 +216,6 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); # SQLSTATE 22007 <invalid datetime value> --error 1411 -INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); ---error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -234,7 +234,7 @@ INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> ---error 1411 +--error 1292 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 69a6dac5381..8f818b60ae7 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -415,8 +415,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, l_time->minute > 59 || l_time->second > 59) goto err; - if ((fuzzy_date & TIME_NO_ZERO_DATE) && - (l_time->year == 0 || l_time->month == 0 || l_time->day == 0)) + int was_cut; + if (check_date(l_time, fuzzy_date | TIME_INVALID_DATES, &was_cut)) goto err; if (val != val_end) @@ -866,7 +866,6 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day); /* Set to NULL if invalid date, but keep the value */ null_value= check_date(<ime, - (ltime.year || ltime.month || ltime.day), (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), &dummy); if (null_value) @@ -1190,7 +1189,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, } MYSQL_TIME ltime; - if (get_arg0_date(<ime, 0)) + if (get_arg0_date(<ime, TIME_NO_ZERO_IN_DATE)) return 1; uint error_code; @@ -2432,8 +2431,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) ltime->time_type= MYSQL_TIMESTAMP_DATE; int unused; - if (check_date(ltime, ltime->year || ltime->month || ltime->day, - fuzzy_date, &unused)) + if (check_date(ltime, fuzzy_date, &unused)) { ErrConvTime str(ltime); make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, diff --git a/sql/sql_time.h b/sql/sql_time.h index c1a75bb2ad3..998d7d78da1 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -110,4 +110,16 @@ extern DATE_TIME_FORMAT global_time_format; extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; extern LEX_STRING interval_type_to_name[]; + +static inline bool +non_zero_date(const MYSQL_TIME *ltime) +{ + return ltime->year || ltime->month || ltime->day; +} +static inline bool +check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut) +{ + return check_date(ltime, non_zero_date(ltime), flags, was_cut); +} + #endif /* SQL_TIME_INCLUDED */ |