summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mats@mysql.com>2006-03-21 14:35:49 +0100
committerunknown <mats@mysql.com>2006-03-21 14:35:49 +0100
commit83ba974a3de1528c7a4749546c1690b66baf4bf3 (patch)
treea303ad6570ce2e7f70c098ba3441aef72e5ee8c8
parentaa3411f54b2d5e2b6069b122085926f771133437 (diff)
downloadmariadb-git-83ba974a3de1528c7a4749546c1690b66baf4bf3.tar.gz
BUG#18293 (Values in stored procedures written to binlog unescaped):
Generating character set-independent quoting of strings for the binary log when executing statements from inside stored procedure. mysql-test/r/ctype_cp932_binlog.result: Result change mysql-test/t/ctype_cp932_binlog.test: Adding check that string literals are written correctly for multi-byte character sets. sql/item.cc: Cutting out character set-independent string escaping code and putting it in a separate function. sql/log_event.cc: Adding characters set-independent code to separate function. sql/mysql_priv.h: Adding new function. sql/sp_head.cc: Escaping string value representing a string item.
-rw-r--r--mysql-test/r/ctype_cp932_binlog.result29
-rw-r--r--mysql-test/t/ctype_cp932_binlog.test23
-rw-r--r--sql/item.cc19
-rw-r--r--sql/log_event.cc31
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sp_head.cc10
6 files changed, 91 insertions, 23 deletions
diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result
index d04fce7738c..6d742f3d464 100644
--- a/mysql-test/r/ctype_cp932_binlog.result
+++ b/mysql-test/r/ctype_cp932_binlog.result
@@ -15,3 +15,32 @@ SELECT HEX(f1) FROM t1;
HEX(f1)
8300
DROP table t1;
+CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
+s2 CHAR(50) CHARACTER SET cp932,
+d DECIMAL(10,2))|
+CREATE PROCEDURE bug18293 (IN ins1 CHAR(50),
+IN ins2 CHAR(50) CHARACTER SET cp932,
+IN ind DECIMAL(10,2))
+BEGIN
+INSERT INTO t4 VALUES (ins1, ins2, ind);
+END|
+CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)|
+SELECT HEX(s1),HEX(s2),d FROM t4|
+HEX(s1) HEX(s2) d
+466F6F2773206120426172 ED40ED41ED42 47.93
+DROP PROCEDURE bug18293|
+DROP TABLE t4|
+SHOW BINLOG EVENTS FROM 393|
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 393 Query 1 556 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
+s2 CHAR(50) CHARACTER SET cp932,
+d DECIMAL(10,2))
+master-bin.000001 556 Query 1 801 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50),
+IN ins2 CHAR(50) CHARACTER SET cp932,
+IN ind DECIMAL(10,2))
+BEGIN
+INSERT INTO t4 VALUES (ins1, ins2, ind);
+END
+master-bin.000001 801 Query 1 1006 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1'Foo\'s a Bar'), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
+master-bin.000001 1006 Query 1 1092 use `test`; DROP PROCEDURE bug18293
+master-bin.000001 1092 Query 1 1168 use `test`; DROP TABLE t4
diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test
index 270e27cf27f..3bbbe94f0e3 100644
--- a/mysql-test/t/ctype_cp932_binlog.test
+++ b/mysql-test/t/ctype_cp932_binlog.test
@@ -32,3 +32,26 @@ DROP table t1;
# end test for bug#11338
# End of 4.1 tests
+
+#
+# Bug#18293: Values in stored procedure written to binlog unescaped
+#
+
+delimiter |;
+CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
+ s2 CHAR(50) CHARACTER SET cp932,
+ d DECIMAL(10,2))|
+CREATE PROCEDURE bug18293 (IN ins1 CHAR(50),
+ IN ins2 CHAR(50) CHARACTER SET cp932,
+ IN ind DECIMAL(10,2))
+ BEGIN
+ INSERT INTO t4 VALUES (ins1, ins2, ind);
+ END|
+CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)|
+SELECT HEX(s1),HEX(s2),d FROM t4|
+DROP PROCEDURE bug18293|
+DROP TABLE t4|
+SHOW BINLOG EVENTS FROM 393|
+delimiter ;|
+
+# End of 5.0 tests
diff --git a/sql/item.cc b/sql/item.cc
index 808271fe256..c48bf19a88b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2642,25 +2642,8 @@ const String *Item_param::query_val_str(String* str) const
case STRING_VALUE:
case LONG_DATA_VALUE:
{
- char *buf, *ptr;
str->length(0);
- if (str->reserve(str_value.length()*2+3))
- break;
-
- buf= str->c_ptr_quick();
- ptr= buf;
- if (value.cs_info.character_set_client->escape_with_backslash_is_dangerous)
- {
- ptr= str_to_hex(ptr, str_value.ptr(), str_value.length());
- }
- else
- {
- *ptr++= '\'';
- ptr+= escape_string_for_mysql(str_value.charset(), ptr, 0,
- str_value.ptr(), str_value.length());
- *ptr++='\'';
- }
- str->length((uint32) (ptr - buf));
+ append_query_string(value.cs_info.character_set_client, &str_value, str);
break;
}
case NULL_VALUE:
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5ca7c00ee8f..266d6b064bd 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -240,6 +240,37 @@ char *str_to_hex(char *to, const char *from, uint len)
}
/*
+ Append a version of the 'from' string suitable for use in a query to
+ the 'to' string. To generate a correct escaping, the character set
+ information in 'csinfo' is used.
+ */
+#ifndef MYSQL_CLIENT
+int
+append_query_string(CHARSET_INFO *csinfo,
+ String const *from, String *to)
+{
+ char *beg, *ptr;
+ uint32 const orig_len= to->length();
+ if (to->reserve(orig_len + from->length()*2+3))
+ return 1;
+
+ beg= to->c_ptr_quick() + to->length();
+ ptr= beg;
+ if (csinfo->escape_with_backslash_is_dangerous)
+ ptr= str_to_hex(ptr, from->ptr(), from->length());
+ else
+ {
+ *ptr++= '\'';
+ ptr+= escape_string_for_mysql(from->charset(), ptr, 0,
+ from->ptr(), from->length());
+ *ptr++='\'';
+ }
+ to->length(orig_len + ptr - beg);
+ return 0;
+}
+#endif
+
+/*
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
commands just before it prints a query.
*/
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 32262b3afb2..9c9d8115402 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -529,6 +529,8 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table);
+int append_query_string(CHARSET_INFO *csinfo,
+ String const *from, String *to);
void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index c0b566f9b9b..bba9479c8f3 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -80,8 +80,8 @@ sp_map_item_type(enum enum_field_types type)
/*
Return a string representation of the Item value.
- NOTE: this is a legacy-compatible implementation. It fails if the value
- contains non-ordinary symbols, which should be escaped.
+ NOTE: If the item has a string result type, the string is escaped
+ according to its character set.
SYNOPSIS
item a pointer to the Item
@@ -119,9 +119,9 @@ sp_get_item_value(Item *item, String *str)
buf.append('_');
buf.append(result->charset()->csname);
- buf.append('\'');
- buf.append(*result);
- buf.append('\'');
+ if (result->charset()->escape_with_backslash_is_dangerous)
+ buf.append(' ');
+ append_query_string(result->charset(), result, &buf);
str->copy(buf);
return str;