diff --git a/mysql-test/r/ctype_errors.result b/mysql-test/r/ctype_errors.result index d8218e40e6f..b3632454eb1 100644 --- a/mysql-test/r/ctype_errors.result +++ b/mysql-test/r/ctype_errors.result @@ -29,4 +29,14 @@ SET lc_messages=cs_CZ; SET NAMES UTF8; USE nonexistant; ERROR 42000: Nezn-Bámá databáze 'nonexistant' -End of 5.4 tests +# +# Bug#12736295: Buffer overflow for variable converted_err +# with non-latin1 server error message +# +# Connection con1 +SET lc_messages=ru_RU; +SET NAMES latin1; +SELECT '01234567890123456789012345678901234\'; +ERROR 42000: \0423 \0432\0430\0441 \043E\0448\0438\0431\043A\0430 \0432 \0437\0430\043F\0440\043E\0441\0435. \0418\0437\0443\0447\0438\0442\0435 \0434\043E\043A\0443\043C\0435\043D\0442\0430\0446\0438\044E \043F\043E \0438\0441\043F\043E\043B\044C\0437\0443\0435\043C\043E\0439 \0432\0435\0440\0441\0438\0438 MySQL \043D\0430 \043F\0440\0435\0434\043C\0435\0442 \043A\043E\0440\0440\0435\043A\0442\043D\043E\0433\043E \0441\0438\043D\0442\0430\043A\0441\0438\0441\0430 \043E\043A\043E\043B\043E ''012345678901234567890123456 +# Connection default +End of 5.5 tests diff --git a/mysql-test/t/ctype_errors.test b/mysql-test/t/ctype_errors.test index 3c73fdae264..681223dae64 100644 --- a/mysql-test/t/ctype_errors.test +++ b/mysql-test/t/ctype_errors.test @@ -44,4 +44,19 @@ USE nonexistant; disconnect con1; connection default; ---echo End of 5.4 tests +--echo # +--echo # Bug#12736295: Buffer overflow for variable converted_err +--echo # with non-latin1 server error message +--echo # + +connect (con1,localhost,root,,test); +--echo # Connection con1 +SET lc_messages=ru_RU; +SET NAMES latin1; +--error ER_PARSE_ERROR +--query SELECT '01234567890123456789012345678901234\' +disconnect con1; +--echo # Connection default +connection default; + +--echo End of 5.5 tests diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 24516f03bee..443f3b7a33e 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -803,14 +803,16 @@ uint32 convert_error_message(char *to, uint32 to_length, CHARSET_INFO *to_cs, my_wc_t wc; const uchar *from_end= (const uchar*) from+from_length; char *to_start= to; - uchar *to_end= (uchar*) to+to_length; + uchar *to_end; my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc; my_charset_conv_wc_mb wc_mb; uint error_count= 0; uint length; DBUG_ASSERT(to_length > 0); + /* Make room for the null terminator. */ to_length--; + to_end= (uchar*) (to + to_length); if (!to_cs || from_cs == to_cs || to_cs == &my_charset_bin) {