Commit cb66cdc6 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-14926 AddressSanitizer: heap-use-after-free in make_date_time on weird...

MDEV-14926 AddressSanitizer: heap-use-after-free in make_date_time on weird combination of functions
parent d7a38eaf
...@@ -3420,5 +3420,21 @@ t2 CREATE TABLE `t2` ( ...@@ -3420,5 +3420,21 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1,t2; DROP TABLE t1,t2;
# #
# MDEV-14926 AddressSanitizer: heap-use-after-free in make_date_time on weird combination of functions
#
DO INET_ATON( FROM_UNIXTIME( @@timestamp, ( TRIM( UNHEX(HEX('%m.%d.%Y') ) ) ) ) );
CREATE TABLE t1 (d DATE);
INSERT INTO t1 VALUES ('1989-03-10');
SELECT TIME_FORMAT('23:59:43', BINARY d) AS f FROM t1 GROUP BY 'foo';
f
1989-03-10
DROP TABLE t1;
CREATE TABLE t1 (d DATE) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('1900-01-01');
SELECT LENGTH( DATE_FORMAT( d, BINARY DATABASE() ) ) AS f FROM t1 GROUP BY d;
f
4
DROP TABLE t1;
#
# End of 10.1 tests # End of 10.1 tests
# #
...@@ -1906,6 +1906,24 @@ SELECT * FROM t2; ...@@ -1906,6 +1906,24 @@ SELECT * FROM t2;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-14926 AddressSanitizer: heap-use-after-free in make_date_time on weird combination of functions
--echo #
DO INET_ATON( FROM_UNIXTIME( @@timestamp, ( TRIM( UNHEX(HEX('%m.%d.%Y') ) ) ) ) );
CREATE TABLE t1 (d DATE);
INSERT INTO t1 VALUES ('1989-03-10');
SELECT TIME_FORMAT('23:59:43', BINARY d) AS f FROM t1 GROUP BY 'foo';
DROP TABLE t1;
CREATE TABLE t1 (d DATE) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('1900-01-01');
SELECT LENGTH( DATE_FORMAT( d, BINARY DATABASE() ) ) AS f FROM t1 GROUP BY d;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
...@@ -455,7 +455,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, ...@@ -455,7 +455,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
Create a formated date/time value in a string. Create a formated date/time value in a string.
*/ */
static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, static bool make_date_time(const LEX_CSTRING &format, MYSQL_TIME *l_time,
timestamp_type type, MY_LOCALE *locale, String *str) timestamp_type type, MY_LOCALE *locale, String *str)
{ {
char intbuff[15]; char intbuff[15];
...@@ -469,7 +469,7 @@ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, ...@@ -469,7 +469,7 @@ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
if (l_time->neg) if (l_time->neg)
str->append('-'); str->append('-');
end= (ptr= format->format.str) + format->format.length; end= (ptr= format.str) + format.length;
for (; ptr != end ; ptr++) for (; ptr != end ; ptr++)
{ {
if (*ptr != '%' || ptr+1 == end) if (*ptr != '%' || ptr+1 == end)
...@@ -1949,6 +1949,7 @@ uint Item_func_date_format::format_length(const String *format) ...@@ -1949,6 +1949,7 @@ uint Item_func_date_format::format_length(const String *format)
String *Item_func_date_format::val_str(String *str) String *Item_func_date_format::val_str(String *str)
{ {
StringBuffer<64> format_buffer;
String *format; String *format;
MYSQL_TIME l_time; MYSQL_TIME l_time;
uint size; uint size;
...@@ -1958,7 +1959,7 @@ String *Item_func_date_format::val_str(String *str) ...@@ -1958,7 +1959,7 @@ String *Item_func_date_format::val_str(String *str)
if (get_arg0_date(&l_time, is_time_flag)) if (get_arg0_date(&l_time, is_time_flag))
return 0; return 0;
if (!(format = args[1]->val_str(str)) || !format->length()) if (!(format= args[1]->val_str(&format_buffer)) || !format->length())
goto null_date; goto null_date;
if (fixed_length) if (fixed_length)
...@@ -1969,18 +1970,13 @@ String *Item_func_date_format::val_str(String *str) ...@@ -1969,18 +1970,13 @@ String *Item_func_date_format::val_str(String *str)
if (size < MAX_DATE_STRING_REP_LENGTH) if (size < MAX_DATE_STRING_REP_LENGTH)
size= MAX_DATE_STRING_REP_LENGTH; size= MAX_DATE_STRING_REP_LENGTH;
if (format == str) DBUG_ASSERT(format != str);
str= &value; // Save result here
if (str->alloc(size)) if (str->alloc(size))
goto null_date; goto null_date;
DATE_TIME_FORMAT date_time_format;
date_time_format.format.str= (char*) format->ptr();
date_time_format.format.length= format->length();
/* Create the result string */ /* Create the result string */
str->set_charset(collation.collation); str->set_charset(collation.collation);
if (!make_date_time(&date_time_format, &l_time, if (!make_date_time(format->lex_cstring(), &l_time,
is_time_format ? MYSQL_TIMESTAMP_TIME : is_time_format ? MYSQL_TIMESTAMP_TIME :
MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATE,
locale, str)) locale, str))
......
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