summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <anozdrin@mysql.com>2006-01-20 15:59:22 +0300
committerunknown <anozdrin@mysql.com>2006-01-20 15:59:22 +0300
commitb688b196979b8385a7463e8dcd83afdd0af6ca69 (patch)
tree09e31d76f40a969088fd9d995a57faf7cac86ad6 /sql
parent1fe1288417285cc6f5c95388bcc3305cfcebc0be (diff)
downloadmariadb-git-b688b196979b8385a7463e8dcd83afdd0af6ca69.tar.gz
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: Update result file. mysql-test/t/type_varchar.test: Add a test for BUG#15588. sql/field.cc: - use memmove() instead of memcpy() -- after implementation of WL#2984 (Make stored routine variables work according to the standard) it is possible to store in the field the value from this field. For instance, this can happen for the following statement: SET sp_var = SUBSTR(sp_var, 1, 3); sql/sp_head.cc: - Work correctly with String: - String length has to be be reset before use; - qs_append() does not allocate memory, so the memory should be reserved beforehand. sql/sql_select.cc: Polishing: should have been done in WL#2984.
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc4
-rw-r--r--sql/sp_head.cc37
-rw-r--r--sql/sql_select.cc2
3 files changed, 28 insertions, 15 deletions
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);
-
- return str;
+ {
+ char buf_holder[STRING_BUFFER_USUAL_SIZE];
+ String buf(buf_holder, sizeof(buf_holder), result->charset());
+
+ /* 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<create_field> &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;