From: Date: July 30 2007 1:35am Subject: bk commit into 5.0 tree (gshchepa:1.2490) BUG#30120 List-Archive: http://lists.mysql.com/commits/31785 X-Bug: 30120 Message-Id: <20070729233522.03A383D40F0@localhost.localdomain> Below is the list of changes that have just been committed into a local 5.0 repository of uchum. When uchum does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-07-30 04:35:16+05:00, gshchepa@stripped +6 -0 Fixed bug #30120. SP with local variables with non-ASCII names crashed the server. The server replaces SP local variable names with NAME_CONST calls when putting statements into the binary log. It used UTF8-encoded item names as variable names for the replacement inside NAME_CONST calls. However, statement string may be encoded by any known character set by the SET NAMES statement. The server used byte length of UTF8-encoded names to increment the position in the query string that led to array index overrun. mysql-test/r/sp.result@stripped, 2007-07-30 04:33:31+05:00, gshchepa@stripped +11 -0 Updated test case for bug #30120. mysql-test/t/sp.test@stripped, 2007-07-30 04:33:10+05:00, gshchepa@stripped +21 -0 Updated test case for bug #30120. sql/item.cc@stripped, 2007-07-30 04:32:48+05:00, gshchepa@stripped +2 -2 Fixed bug #30120. The Item_splocal class constructor has been modified to accept new parameter `len_in_q': the byte length of variable name in the query string. sql/item.h@stripped, 2007-07-30 04:33:00+05:00, gshchepa@stripped +10 -1 Fixed bug #30120. The Item_splocal class has been modified to keep new field `len_in_query': the byte length of variable name in the query string. sql/sp_head.cc@stripped, 2007-07-30 04:33:05+05:00, gshchepa@stripped +1 -1 Fixed bug #30120. The subst_spvars function has been modified to increment position in the query string by the lengths of not encoded variable names instead of byte length of names encoded to UTF-8. sql/sql_yacc.yy@stripped, 2007-07-30 04:33:07+05:00, gshchepa@stripped +2 -1 Fixed bug #30120. The simple_ident rule action has been modified to pass the byte length of the local variable name token to the Item_splocal object constructor. diff -Nrup a/mysql-test/r/sp.result b/mysql-test/r/sp.result --- a/mysql-test/r/sp.result 2007-07-28 23:36:25 +05:00 +++ b/mysql-test/r/sp.result 2007-07-30 04:33:31 +05:00 @@ -6303,4 +6303,15 @@ DROP VIEW v1; DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1; +SET NAMES latin1; +CREATE PROCEDURE p1() +BEGIN +DECLARE бвд INT; +SELECT бвд; +END| +CALL p1(); +бвд +NULL +SET NAMES default; +DROP PROCEDURE p1; End of 5.0 tests diff -Nrup a/mysql-test/t/sp.test b/mysql-test/t/sp.test --- a/mysql-test/t/sp.test 2007-07-28 23:36:25 +05:00 +++ b/mysql-test/t/sp.test 2007-07-30 04:33:10 +05:00 @@ -7278,4 +7278,25 @@ DROP FUNCTION f1; DROP FUNCTION f2; DROP TABLE t1; +# +# Bug #30120 SP with local variables with non-ASCII names crashes server. +# + +SET NAMES latin1; + +DELIMITER |; + +CREATE PROCEDURE p1() +BEGIN + DECLARE бвд INT; + SELECT бвд; +END| + +DELIMITER ;| + +CALL p1(); + +SET NAMES default; +DROP PROCEDURE p1; + --echo End of 5.0 tests diff -Nrup a/sql/item.cc b/sql/item.cc --- a/sql/item.cc 2007-07-27 18:42:24 +05:00 +++ b/sql/item.cc 2007-07-30 04:32:48 +05:00 @@ -1053,9 +1053,9 @@ bool Item_sp_variable::is_null() Item_splocal::Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx, enum_field_types sp_var_type, - uint pos_in_q) + uint pos_in_q, uint len_in_q) :Item_sp_variable(sp_var_name.str, sp_var_name.length), - m_var_idx(sp_var_idx), pos_in_query(pos_in_q) + m_var_idx(sp_var_idx), pos_in_query(pos_in_q), len_in_query(len_in_q) { maybe_null= TRUE; diff -Nrup a/sql/item.h b/sql/item.h --- a/sql/item.h 2007-07-27 18:42:24 +05:00 +++ b/sql/item.h 2007-07-30 04:33:00 +05:00 @@ -960,9 +960,18 @@ public: SP variable in query text. */ uint pos_in_query; + /* + Byte length of SP variable name in the statement (see pos_in_query). + The value of this field may differ from the name_length value because + name_length contains byte length of UTF8-encoded item name, but + the query string (see sp_instr_stmt::m_query) is currently stored with + a charset from the SET NAMES statement. + */ + uint len_in_query; Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx, - enum_field_types sp_var_type, uint pos_in_q= 0); + enum_field_types sp_var_type, + uint pos_in_q= 0, uint len_in_q= 0); bool is_splocal() { return 1; } /* Needed for error checking */ diff -Nrup a/sql/sp_head.cc b/sql/sp_head.cc --- a/sql/sp_head.cc 2007-07-28 23:42:31 +05:00 +++ b/sql/sp_head.cc 2007-07-30 04:33:05 +05:00 @@ -864,7 +864,7 @@ subst_spvars(THD *thd, sp_instr *instr, /* append the text between sp ref occurences */ res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos); - prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length; + prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query; /* append the spvar substitute */ res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('")); diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy --- a/sql/sql_yacc.yy 2007-07-17 00:40:31 +05:00 +++ b/sql/sql_yacc.yy 2007-07-30 04:33:07 +05:00 @@ -7708,7 +7708,8 @@ simple_ident: Item_splocal *splocal; splocal= new Item_splocal($1, spv->offset, spv->type, lip->tok_start_prev - - lex->sphead->m_tmp_query); + lex->sphead->m_tmp_query, + lip->tok_end - lip->tok_start_prev); #ifndef DBUG_OFF if (splocal) splocal->m_sp= lex->sphead;