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;