Commit 4085836a authored by Alexander Barkov's avatar Alexander Barkov

MDEV-4635 Crash in UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))

modified:
  mysql-test/r/func_time.result
  mysql-test/t/func_time.test
  sql/item_timefunc.cc
  sql/mysql_priv.h
parent fee78df3
...@@ -1910,3 +1910,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12')); ...@@ -1910,3 +1910,13 @@ SELECT 1 FROM DUAL WHERE MINUTE(TIMEDIFF(NULL, '12:12:12'));
1 1
SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12')); SELECT 1 FROM DUAL WHERE SECOND(TIMEDIFF(NULL, '12:12:12'));
1 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:
Error 1411 Incorrect datetime value: '2020' for function str_to_date
SET TIME_ZONE=DEFAULT;
...@@ -1154,3 +1154,11 @@ SELECT 1 FROM DUAL WHERE DAYOFMONTH(TIMEDIFF(NULL, '12:12:12')); ...@@ -1154,3 +1154,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 HOUR(TIMEDIFF(NULL, '12:12:12'));
SELECT 1 FROM DUAL WHERE MINUTE(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')); 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;
...@@ -396,8 +396,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, ...@@ -396,8 +396,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
l_time->minute > 59 || l_time->second > 59) l_time->minute > 59 || l_time->second > 59)
goto err; goto err;
if ((fuzzy_date & TIME_NO_ZERO_DATE) && int was_cut;
(l_time->year == 0 || l_time->month == 0 || l_time->day == 0)) if (check_date(l_time, fuzzy_date | TIME_INVALID_DATES, &was_cut))
goto err; goto err;
if (val != val_end) if (val != val_end)
...@@ -799,7 +799,6 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp) ...@@ -799,7 +799,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); res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
/* Set to NULL if invalid date, but keep the value */ /* Set to NULL if invalid date, but keep the value */
null_value= check_date(&ltime, null_value= check_date(&ltime,
(ltime.year || ltime.month || ltime.day),
(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
&dummy); &dummy);
if (null_value) if (null_value)
...@@ -1126,7 +1125,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, ...@@ -1126,7 +1125,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
} }
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_arg0_date(&ltime, 0)) if (get_arg0_date(&ltime, TIME_NO_ZERO_IN_DATE))
return 1; return 1;
uint error_code; uint error_code;
...@@ -2309,8 +2308,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) ...@@ -2309,8 +2308,7 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
ltime->time_type= MYSQL_TIMESTAMP_DATE; ltime->time_type= MYSQL_TIMESTAMP_DATE;
int unused; int unused;
if (check_date(ltime, ltime->year || ltime->month || ltime->day, if (check_date(ltime, fuzzy_date, &unused))
fuzzy_date, &unused))
{ {
Lazy_string_time str(ltime); Lazy_string_time str(ltime);
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
......
...@@ -2558,7 +2558,16 @@ extern bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, ...@@ -2558,7 +2558,16 @@ extern bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b); int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item *warn_item, bool *is_null); Item *warn_item, bool *is_null);
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);
}
int test_if_number(char *str,int *res,bool allow_wildcards); int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(uchar *,uint,char,char); void change_byte(uchar *,uint,char,char);
bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment