Skip to content

Commit

Permalink
fix string literal escaping in views
Browse files Browse the repository at this point in the history
process multibyte characters correctly, don't escape half of the character
  • Loading branch information
vuvova committed Jun 2, 2023
1 parent 69684f6 commit c05ecda
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 23 deletions.
11 changes: 10 additions & 1 deletion mysql-test/include/ctype_E05C.inc
Expand Up @@ -76,6 +76,15 @@ INSERT INTO t1 VALUES (_BINARY'\\''
SELECT a, HEX(a) FROM t1;
DROP TABLE t1;
#
# test how strings are written into view's frm
#
disable_view_protocol;
create view v1 as select hex('à\'), hex('à\t');
select * from v1;
drop view v1;
enable_view_protocol;
# Checking that with character_set_client=binary 0x5C in 0xE05C
# is treated as escape rather than the second byte of a multi-byte character,
# even if character_set_connection is big5/cp932/gbk/sjis.
Expand Down Expand Up @@ -109,5 +118,5 @@ SELECT HEX(a) FROM t1;
DROP TABLE t1;
--enable_view_protocol
--echo # Start of ctype_E05C.inc
--echo # End of ctype_E05C.inc
13 changes: 9 additions & 4 deletions mysql-test/main/ctype_big5.result
Expand Up @@ -537,15 +537,15 @@ create table t1 (a blob);
insert into t1 values (0xEE00);
select * into outfile 'test/t1.txt' from t1;
delete from t1;
select hex(load_file('MYSQLD_DATADIR/test/t1.txt'));;
hex(load_file('MYSQLD_DATADIR/test/t1.txt'))
select hex(load_file('MYSQLD_DATADIR/test/t1.txt')) as lf;
lf
5CEE5C300A
load data infile 't1.txt' into table t1;
select hex(a) from t1;
hex(a)
EE00
drop table t1;
End of 5.0 tests
# End of 5.0 tests
#
# Start of 5.5 tests
#
Expand Down Expand Up @@ -4705,6 +4705,11 @@ a HEX(a)
\'�\ 5C27E05C
�\'\ E05C275C
DROP TABLE t1;
create view v1 as select hex('�\'), hex('�\t');
select * from v1;
hex('�\') hex('�\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results
Expand Down Expand Up @@ -4744,7 +4749,7 @@ HEX(a)
E05C5B
E05B
DROP TABLE t1;
# Start of ctype_E05C.inc
# End of ctype_E05C.inc
SET NAMES big5;
CREATE TABLE t1 (a ENUM('�@') CHARACTER SET big5);
SHOW CREATE TABLE t1;
Expand Down
7 changes: 2 additions & 5 deletions mysql-test/main/ctype_big5.test
Expand Up @@ -79,18 +79,15 @@ create table t1 (a blob);
insert into t1 values (0xEE00);
select * into outfile 'test/t1.txt' from t1;
delete from t1;
#enable after fix MDEV-27871
--disable_view_protocol
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
--eval select hex(load_file('$MYSQLD_DATADIR/test/t1.txt'));
--eval select hex(load_file('$MYSQLD_DATADIR/test/t1.txt')) as lf
load data infile 't1.txt' into table t1;
select hex(a) from t1;
--remove_file $MYSQLD_DATADIR/test/t1.txt
drop table t1;
#enable_view_protocol
#
--echo End of 5.0 tests
--echo # End of 5.0 tests


--echo #
Expand Down
7 changes: 6 additions & 1 deletion mysql-test/main/ctype_cp932_binlog_stm.result
Expand Up @@ -20413,6 +20413,11 @@ a HEX(a)
\'�\ 5C27E05C
�\'\ E05C275C
DROP TABLE t1;
create view v1 as select hex('�\'), hex('�\t');
select * from v1;
hex('�\') hex('�\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results
Expand Down Expand Up @@ -20452,7 +20457,7 @@ HEX(a)
E05C5B
E05B
DROP TABLE t1;
# Start of ctype_E05C.inc
# End of ctype_E05C.inc
#
# End of 10.0 tests
#
7 changes: 6 additions & 1 deletion mysql-test/main/ctype_gbk.result
Expand Up @@ -5053,6 +5053,11 @@ a HEX(a)
\'�\ 5C27E05C
�\'\ E05C275C
DROP TABLE t1;
create view v1 as select hex('�\'), hex('�\t');
select * from v1;
hex('�\') hex('�\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results
Expand Down Expand Up @@ -5092,7 +5097,7 @@ HEX(a)
E05C5B
E05B
DROP TABLE t1;
# Start of ctype_E05C.inc
# End of ctype_E05C.inc
SET NAMES utf8, character_set_connection=gbk;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
Expand Down
7 changes: 6 additions & 1 deletion mysql-test/main/ctype_sjis.result
Expand Up @@ -18677,6 +18677,11 @@ a HEX(a)
\'�\ 5C27E05C
�\'\ E05C275C
DROP TABLE t1;
create view v1 as select hex('�\'), hex('�\t');
select * from v1;
hex('�\') hex('�\t')
E05C E05C74
drop view v1;
SET character_set_client=binary, character_set_results=binary;
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
@@character_set_client @@character_set_connection @@character_set_results
Expand Down Expand Up @@ -18716,7 +18721,7 @@ HEX(a)
E05C5B
E05B
DROP TABLE t1;
# Start of ctype_E05C.inc
# End of ctype_E05C.inc
#
# End of 10.0 tests
#
Expand Down
26 changes: 16 additions & 10 deletions sql/sql_string.cc
Expand Up @@ -1115,22 +1115,28 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs,
characters with backslashes as necessary.
Does not add the enclosing quotes, this is left up to caller.
*/
#define APPEND(X) if (append(X)) return 1; else break
#define APPEND(...) if (append(__VA_ARGS__)) return 1;
bool String::append_for_single_quote(const char *st, size_t len)
{
const char *end= st+len;
int chlen;
for (; st < end; st++)
{
uchar c= *st;
switch (c)
switch (*st)
{
case '\\': APPEND(STRING_WITH_LEN("\\\\"));
case '\0': APPEND(STRING_WITH_LEN("\\0"));
case '\'': APPEND(STRING_WITH_LEN("\\'"));
case '\n': APPEND(STRING_WITH_LEN("\\n"));
case '\r': APPEND(STRING_WITH_LEN("\\r"));
case '\032': APPEND(STRING_WITH_LEN("\\Z"));
default: APPEND(c);
case '\\': APPEND(STRING_WITH_LEN("\\\\")); break;
case '\0': APPEND(STRING_WITH_LEN("\\0")); break;
case '\'': APPEND(STRING_WITH_LEN("\\'")); break;
case '\n': APPEND(STRING_WITH_LEN("\\n")); break;
case '\r': APPEND(STRING_WITH_LEN("\\r")); break;
case '\032': APPEND(STRING_WITH_LEN("\\Z")); break;
default: if ((chlen= my_charlen(charset(), st, end)) > 0)
{
APPEND(st, chlen);
st+= chlen-1;
}
else
APPEND(*st);
}
}
return 0;
Expand Down

0 comments on commit c05ecda

Please sign in to comment.