summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2021-11-02 09:00:49 +0400
committerAlexander Barkov <bar@mariadb.com>2021-11-02 09:00:49 +0400
commitd0b611a76d91a5b6dbbc8fab792d7daaaaa862f5 (patch)
treee0102ee1fafc12825998f13da009c2c960a89d40
parent026984c360ce27c62072ed6ce798ec855952c974 (diff)
downloadmariadb-git-d0b611a76d91a5b6dbbc8fab792d7daaaaa862f5.tar.gz
MDEV-24335 Unexpected question mark in the end of a TINYTEXT column
my_copy_fix_mb() passed MIN(src_length,dst_length) to my_append_fix_badly_formed_tail(). It could break a multi-byte character in the middle, which put the question mark to the destination. Fixing the code to pass the true src_length to my_append_fix_badly_formed_tail().
-rw-r--r--mysql-test/r/ctype_utf8.result11
-rw-r--r--mysql-test/t/ctype_utf8.test9
-rw-r--r--strings/ctype-mb.c4
3 files changed, 22 insertions, 2 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 18398f2556a..96fdac1caba 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -11256,5 +11256,16 @@ DROP TABLE kv;
DROP VIEW v1;
SET NAMES utf8;
#
+# MDEV-24335 Unexpected question mark in the end of a TINYTEXT column
+#
+CREATE TABLE t1 (a TINYTEXT character set utf8);
+INSERT IGNORE INTO t1 VALUES (REPEAT(_utf8 0xD184, 250));
+Warnings:
+Warning 1366 Incorrect string value: '\xD1\x84\xD1\x84\xD1\x84...' for column `test`.`t1`.`a` at row 1
+SELECT LENGTH(a), CHAR_LENGTH(a), RIGHT(a,3) FROM t1;
+LENGTH(a) CHAR_LENGTH(a) RIGHT(a,3)
+254 127 ффф
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index b34de4175e9..991c2e100c9 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -2184,5 +2184,14 @@ DROP VIEW v1;
SET NAMES utf8;
--echo #
+--echo # MDEV-24335 Unexpected question mark in the end of a TINYTEXT column
+--echo #
+
+CREATE TABLE t1 (a TINYTEXT character set utf8);
+INSERT IGNORE INTO t1 VALUES (REPEAT(_utf8 0xD184, 250));
+SELECT LENGTH(a), CHAR_LENGTH(a), RIGHT(a,3) FROM t1;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index cabc940065b..caeb9f95ef1 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -401,10 +401,10 @@ my_copy_fix_mb(CHARSET_INFO *cs,
size_t well_formed_nchars;
size_t well_formed_length;
size_t fixed_length;
+ size_t min_length= MY_MIN(src_length, dst_length);
- set_if_smaller(src_length, dst_length);
well_formed_nchars= cs->cset->well_formed_char_length(cs,
- src, src + src_length,
+ src, src + min_length,
nchars, status);
DBUG_ASSERT(well_formed_nchars <= nchars);
well_formed_length= status->m_source_end_pos - src;