Skip to content

Commit ff2d92b

Browse files
author
Alexander Barkov
committed
MDEV-7231 Field ROUTINE_DEFINITION in INFORMATION_SCHEMA.ROUTINES
contains broken procedure body when used shielding quotes inside.
1 parent 28a36f6 commit ff2d92b

File tree

8 files changed

+516
-45
lines changed

8 files changed

+516
-45
lines changed

include/m_ctype.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ struct my_charset_handler_st
533533

534534
extern MY_CHARSET_HANDLER my_charset_8bit_handler;
535535
extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
536+
extern MY_CHARSET_HANDLER my_charset_utf8_handler;
536537

537538

538539
/*
@@ -889,6 +890,18 @@ uint32 my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
889890
const char *from, uint32 from_length,
890891
CHARSET_INFO *from_cs, uint *errors);
891892

893+
/**
894+
An extended version of my_convert(), to pass non-default mb_wc() and wc_mb().
895+
For example, String::copy_printable() which is used in
896+
Protocol::store_warning() uses this to escape control
897+
and non-convertable characters.
898+
*/
899+
uint32 my_convert_using_func(char *to, uint32 to_length, CHARSET_INFO *to_cs,
900+
my_charset_conv_wc_mb mb_wc,
901+
const char *from, uint32 from_length,
902+
CHARSET_INFO *from_cs,
903+
my_charset_conv_mb_wc wc_mb,
904+
uint *errors);
892905
/*
893906
Convert a string between two character sets.
894907
Bad byte sequences as well as characters that cannot be

mysql-test/r/ctype_utf8.result

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10259,5 +10259,146 @@ Warnings:
1025910259
Note 1003 select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'A')
1026010260
DROP TABLE t1;
1026110261
#
10262+
# MDEV-7231 Field ROUTINE_DEFINITION in INFORMATION_SCHEMA.`ROUTINES` contains broken procedure body when used shielding quotes inside.
10263+
#
10264+
CREATE PROCEDURE p1()
10265+
BEGIN
10266+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10267+
SELECT '''', """", '\'', "\"";
10268+
SELECT '<tab> <tab>\t<tab>';
10269+
SELECT '<nl>
10270+
<nl>\n<nl>';
10271+
SELECT 'test';
10272+
SELECT 'tëst';
10273+
SELECT 'test\0';
10274+
SELECT 'tëst\0';
10275+
SELECT _binary'test';
10276+
SELECT _binary'test\0';
10277+
SELECT N'''', N"""", N'\'', N"\"";
10278+
SELECT N'<tab> <tab>\t<tab>';
10279+
SELECT N'<nl>
10280+
<nl>\n<nl>';
10281+
SELECT N'test';
10282+
SELECT N'tëst';
10283+
SELECT N'test\0';
10284+
SELECT N'tëst\0';
10285+
END$$
10286+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
10287+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='p1';
10288+
ROUTINE_DEFINITION
10289+
BEGIN
10290+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10291+
SELECT '''', """", '''', """";
10292+
SELECT '<tab>\t<tab>\t<tab>';
10293+
SELECT '<nl>\n<nl>\n<nl>';
10294+
SELECT 'test';
10295+
SELECT 'tëst';
10296+
SELECT 'test\0';
10297+
SELECT 'tëst\0';
10298+
SELECT 'test';
10299+
SELECT 'test\0';
10300+
SELECT N'''', N"""", N'''', N"""";
10301+
SELECT N'<tab>\t<tab>\t<tab>';
10302+
SELECT N'<nl>\n<nl>\n<nl>';
10303+
SELECT N'test';
10304+
SELECT N'tëst';
10305+
SELECT N'test\0';
10306+
SELECT N'tëst\0';
10307+
END
10308+
SELECT body_utf8 FROM mysql.proc WHERE name='p1';
10309+
body_utf8
10310+
BEGIN
10311+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10312+
SELECT '''', """", '''', """";
10313+
SELECT '<tab>\t<tab>\t<tab>';
10314+
SELECT '<nl>\n<nl>\n<nl>';
10315+
SELECT 'test';
10316+
SELECT 'tëst';
10317+
SELECT 'test\0';
10318+
SELECT 'tëst\0';
10319+
SELECT 'test';
10320+
SELECT 'test\0';
10321+
SELECT N'''', N"""", N'''', N"""";
10322+
SELECT N'<tab>\t<tab>\t<tab>';
10323+
SELECT N'<nl>\n<nl>\n<nl>';
10324+
SELECT N'test';
10325+
SELECT N'tëst';
10326+
SELECT N'test\0';
10327+
SELECT N'tëst\0';
10328+
END
10329+
DROP PROCEDURE p1;
10330+
SET @@SQL_MODE='NO_BACKSLASH_ESCAPES';
10331+
CREATE PROCEDURE p1()
10332+
BEGIN
10333+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10334+
SELECT '''', """";
10335+
SELECT '<tab> <tab>\t<tab>';
10336+
SELECT '<nl>
10337+
<nl>\n<nl>';
10338+
SELECT 'test';
10339+
SELECT 'tëst';
10340+
SELECT 'test\0';
10341+
SELECT 'tëst\0';
10342+
SELECT _binary'test';
10343+
SELECT _binary'test\0';
10344+
SELECT N'''', N"""";
10345+
SELECT N'<tab> <tab>\t<tab>';
10346+
SELECT N'<nl>
10347+
<nl>\n<nl>';
10348+
SELECT N'test';
10349+
SELECT N'tëst';
10350+
SELECT N'test\0';
10351+
SELECT N'tëst\0';
10352+
END$$
10353+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
10354+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='p1';
10355+
ROUTINE_DEFINITION
10356+
BEGIN
10357+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10358+
SELECT '''', """";
10359+
SELECT '<tab> <tab>\t<tab>';
10360+
SELECT '<nl>
10361+
<nl>\n<nl>';
10362+
SELECT 'test';
10363+
SELECT 'tëst';
10364+
SELECT 'test\0';
10365+
SELECT 'tëst\0';
10366+
SELECT 'test';
10367+
SELECT 'test\0';
10368+
SELECT N'''', N"""";
10369+
SELECT N'<tab> <tab>\t<tab>';
10370+
SELECT N'<nl>
10371+
<nl>\n<nl>';
10372+
SELECT N'test';
10373+
SELECT N'tëst';
10374+
SELECT N'test\0';
10375+
SELECT N'tëst\0';
10376+
END
10377+
SELECT body_utf8 FROM mysql.proc WHERE name='p1';
10378+
body_utf8
10379+
BEGIN
10380+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
10381+
SELECT '''', """";
10382+
SELECT '<tab> <tab>\t<tab>';
10383+
SELECT '<nl>
10384+
<nl>\n<nl>';
10385+
SELECT 'test';
10386+
SELECT 'tëst';
10387+
SELECT 'test\0';
10388+
SELECT 'tëst\0';
10389+
SELECT 'test';
10390+
SELECT 'test\0';
10391+
SELECT N'''', N"""";
10392+
SELECT N'<tab> <tab>\t<tab>';
10393+
SELECT N'<nl>
10394+
<nl>\n<nl>';
10395+
SELECT N'test';
10396+
SELECT N'tëst';
10397+
SELECT N'test\0';
10398+
SELECT N'tëst\0';
10399+
END
10400+
DROP PROCEDURE p1;
10401+
SET @@SQL_MODE=default;
10402+
#
1026210403
# End of 10.1 tests
1026310404
#

mysql-test/r/ctype_utf8mb4.result

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3382,5 +3382,19 @@ SET NAMES utf8mb4;
33823382
SELECT * FROM `test😁😁test`;
33833383
ERROR HY000: Invalid utf8mb4 character string: 'test\xF0\x9F\x98\x81\xF0\x9F\x98\x81test'
33843384
#
3385+
# MDEV-7231 Field ROUTINE_DEFINITION in INFORMATION_SCHEMA.`ROUTINES` contains broken procedure body when used shielding quotes inside.
3386+
#
3387+
SET NAMES utf8mb4;
3388+
CREATE FUNCTION f1() RETURNS TEXT CHARACTER SET utf8mb4
3389+
RETURN CONCAT('😎','x😎','😎y','x😎y');
3390+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
3391+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='f1';
3392+
ROUTINE_DEFINITION
3393+
RETURN CONCAT('?','x?','?y','x?y')
3394+
SELECT body_utf8 FROM mysql.proc WHERE name='f1';
3395+
body_utf8
3396+
RETURN CONCAT('?','x?','?y','x?y')
3397+
DROP FUNCTION f1;
3398+
#
33853399
# End of 10.1 tests
33863400
#

mysql-test/t/ctype_utf8.test

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,82 @@ SELECT * FROM t1 WHERE c>=_utf8'a' COLLATE utf8_general_ci AND c='A';
18711871
DROP TABLE t1;
18721872

18731873

1874+
--echo #
1875+
--echo # MDEV-7231 Field ROUTINE_DEFINITION in INFORMATION_SCHEMA.`ROUTINES` contains broken procedure body when used shielding quotes inside.
1876+
--echo #
1877+
DELIMITER $$;
1878+
CREATE PROCEDURE p1()
1879+
BEGIN
1880+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
1881+
SELECT '''', """", '\'', "\"";
1882+
SELECT '<tab> <tab>\t<tab>';
1883+
SELECT '<nl>
1884+
<nl>\n<nl>';
1885+
SELECT 'test';
1886+
SELECT 'tëst';
1887+
SELECT 'test\0';
1888+
SELECT 'tëst\0';
1889+
SELECT _binary'test';
1890+
SELECT _binary'test\0';
1891+
SELECT N'''', N"""", N'\'', N"\"";
1892+
SELECT N'<tab> <tab>\t<tab>';
1893+
SELECT N'<nl>
1894+
<nl>\n<nl>';
1895+
SELECT N'test';
1896+
SELECT N'tëst';
1897+
SELECT N'test\0';
1898+
SELECT N'tëst\0';
1899+
END$$
1900+
DELIMITER ;$$
1901+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
1902+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='p1';
1903+
SELECT body_utf8 FROM mysql.proc WHERE name='p1';
1904+
DROP PROCEDURE p1;
1905+
1906+
SET @@SQL_MODE='NO_BACKSLASH_ESCAPES';
1907+
DELIMITER $$;
1908+
CREATE PROCEDURE p1()
1909+
BEGIN
1910+
SELECT CONCAT('ABC = ''',1,''''), CONCAT('ABC = ',2);
1911+
SELECT '''', """";
1912+
SELECT '<tab> <tab>\t<tab>';
1913+
SELECT '<nl>
1914+
<nl>\n<nl>';
1915+
SELECT 'test';
1916+
SELECT 'tëst';
1917+
SELECT 'test\0';
1918+
SELECT 'tëst\0';
1919+
SELECT _binary'test';
1920+
SELECT _binary'test\0';
1921+
SELECT N'''', N"""";
1922+
SELECT N'<tab> <tab>\t<tab>';
1923+
SELECT N'<nl>
1924+
<nl>\n<nl>';
1925+
SELECT N'test';
1926+
SELECT N'tëst';
1927+
SELECT N'test\0';
1928+
SELECT N'tëst\0';
1929+
END$$
1930+
DELIMITER ;$$
1931+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
1932+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='p1';
1933+
SELECT body_utf8 FROM mysql.proc WHERE name='p1';
1934+
DROP PROCEDURE p1;
1935+
SET @@SQL_MODE=default;
1936+
1937+
1938+
# TODO: Uncomment the below test whe we fix:
1939+
# MDEV-9623INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITION does not handle binary literals well
1940+
#
1941+
#SET NAMES binary;
1942+
#CREATE FUNCTION f1() RETURNS TEXT RETURN CONCAT('i','й');
1943+
#SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
1944+
#WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='f1';
1945+
#SELECT body_utf8 FROM mysql.proc WHERE name='f1';
1946+
#DROP FUNCTION f1;
1947+
#SET NAMES utf8;
1948+
1949+
18741950
--echo #
18751951
--echo # End of 10.1 tests
18761952
--echo #

mysql-test/t/ctype_utf8mb4.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,18 @@ SET NAMES utf8mb4;
19041904
--error ER_INVALID_CHARACTER_STRING
19051905
SELECT * FROM `test😁😁test`;
19061906

1907+
--echo #
1908+
--echo # MDEV-7231 Field ROUTINE_DEFINITION in INFORMATION_SCHEMA.`ROUTINES` contains broken procedure body when used shielding quotes inside.
1909+
--echo #
1910+
# Non-BMP characters should be replaced to '?' in ROUTINE_DEFINITION/body_utf8
1911+
SET NAMES utf8mb4;
1912+
CREATE FUNCTION f1() RETURNS TEXT CHARACTER SET utf8mb4
1913+
RETURN CONCAT('😎','x😎','😎y','x😎y');
1914+
SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES
1915+
WHERE ROUTINE_SCHEMA='test' AND SPECIFIC_NAME ='f1';
1916+
SELECT body_utf8 FROM mysql.proc WHERE name='f1';
1917+
DROP FUNCTION f1;
1918+
19071919
--echo #
19081920
--echo # End of 10.1 tests
19091921
--echo #

0 commit comments

Comments
 (0)