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.
This commit is contained in:
parent
1fe1288417
commit
b688b19697
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user