From 145fd62bc12285db199af8b9c49e0428f44ff69c Mon Sep 17 00:00:00 2001 From: "anozdrin@mysql.com" <> Date: Fri, 20 Jan 2006 15:59:22 +0300 Subject: [PATCH] Fix for BUG#15588: String overrun during sp-vars.test The bug appears after implementation of WL#2984 (Make stored routine variables work according to the standard). --- mysql-test/r/type_varchar.result | 7 +++++++ mysql-test/t/type_varchar.test | 16 +++++++++++++++ sql/field.cc | 4 ++-- sql/sp_head.cc | 35 ++++++++++++++++++++++---------- sql/sql_select.cc | 2 +- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index e3b12cc36e3..e74850bba33 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -415,3 +415,10 @@ t1 CREATE TABLE `t1` ( KEY `index1` (`f1`(10)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(f1 VARCHAR(100) DEFAULT 'test'); +INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test'); +INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test index 1a3a93018a4..2d2314f0a29 100644 --- a/mysql-test/t/type_varchar.test +++ b/mysql-test/t/type_varchar.test @@ -130,3 +130,19 @@ show create table t1; alter table t1 modify f1 tinytext; show create table t1; drop table t1; + +# +# BUG#15588: String overrun +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1(f1 VARCHAR(100) DEFAULT 'test'); +INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test'); +INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); +DROP TABLE IF EXISTS t1; diff --git a/sql/field.cc b/sql/field.cc index df76eb729f8..0d48d4ae004 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5873,7 +5873,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) field_length/ field_charset->mbmaxlen, &well_formed_error); - memcpy(ptr,from,copy_length); + memmove(ptr, from, copy_length); /* Append spaces if the string was shorter than the field. */ if (copy_length < field_length) @@ -6266,7 +6266,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) field_length/ field_charset->mbmaxlen, &well_formed_error); - memcpy(ptr + length_bytes, from, copy_length); + memmove(ptr + length_bytes, from, copy_length); if (length_bytes == 1) *ptr= (uchar) copy_length; else diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f42fbef82e3..ae27b910304 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -105,21 +105,27 @@ sp_get_item_value(Item *item, String *str) case STRING_RESULT: { - char buf_holder[STRING_BUFFER_USUAL_SIZE]; - String buf(buf_holder, sizeof(buf_holder), &my_charset_latin1); String *result= item->val_str(str); if (!result) return NULL; - buf.append('_'); - buf.append(result->charset()->csname); - buf.append('\''); - buf.append(*result); - buf.append('\''); - str->copy(buf); + { + char buf_holder[STRING_BUFFER_USUAL_SIZE]; + String buf(buf_holder, sizeof(buf_holder), result->charset()); - return str; + /* We must reset length of the buffer, because of String specificity. */ + buf.length(0); + + buf.append('_'); + buf.append(result->charset()->csname); + buf.append('\''); + buf.append(*result); + buf.append('\''); + str->copy(buf); + + return str; + } } case ROW_RESULT: @@ -3085,9 +3091,16 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp) void sp_instr_set_case_expr::print(String *str) { - str->append(STRING_WITH_LEN("set_case_expr ")); + const char CASE_EXPR_TAG[]= "set_case_expr "; + const int CASE_EXPR_TAG_LEN= sizeof(CASE_EXPR_TAG) - 1; + const int INT_STRING_MAX_LEN= 10; + + /* We must call reserve(), because qs_append() doesn't care about memory. */ + str->reserve(CASE_EXPR_TAG_LEN + INT_STRING_MAX_LEN + 2); + + str->qs_append(CASE_EXPR_TAG, CASE_EXPR_TAG_LEN); str->qs_append(m_case_expr_id); - str->append(' '); + str->qs_append(' '); m_case_expr->print(str); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index be255d1f790..1037f490397 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9046,7 +9046,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List &field_list) ++field; } - *field= NULL; /* mark the end of the list */ + *field= NULL; /* mark the end of the list */ s->blob_field[blob_count]= 0; /* mark the end of the list */ s->blob_fields= blob_count;