From b8ea2ec7b027d87c28fc8a2943adab254b22e2ac Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Mon, 6 Jul 2026 18:25:08 -0600 Subject: [PATCH] MDEV-40270 @@default_master_connection does not convert character sets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Item::val_str()` doesn’t specify the collation of the returned string, yet `Sys_var_session_lexstring::do_check()` (for `@@default_master_connection`) and `Sys_var_debug_sync::do_check()` (for `@@debug_sync`) assume the `@@character_set_system` collation. This commit replaces `Sys_var_debug_sync::do_check()` with a delegate to `Sys_var_charptr::do_string_check()` to match `Sys_var_dbug::do_check()`, as neither of those has this bug. It ports the character set conversion to `Sys_var_session_lexstring::do_check()` rather than delegating, so the length check is not after a memory allocation; this class has been refactored away in 11.3 (Commit 6151bde48c) anyway. --- mysql-test/main/null_conn.result | 7 +++++ .../suite/sys_vars/r/debug_sync_basic.result | 5 ++++ .../r/default_master_connection_basic.result | 5 ++++ .../suite/sys_vars/t/debug_sync_basic.test | 5 ++++ .../t/default_master_connection_basic.test | 7 +++++ sql/sys_vars.inl | 29 +++++++++++-------- 6 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 mysql-test/main/null_conn.result diff --git a/mysql-test/main/null_conn.result b/mysql-test/main/null_conn.result new file mode 100644 index 0000000000000..fce249c1189b8 --- /dev/null +++ b/mysql-test/main/null_conn.result @@ -0,0 +1,7 @@ +CHANGE MASTER TO master_host='127.0.0.1\0hulu', master_user='root\0bulu'; +SET @@GLOBAL.replicate_do_db= 'A\0Z'; +SELECT @@GLOBAL.replicate_do_db; +@@GLOBAL.replicate_do_db +A +SET @@GLOBAL.replicate_do_db= DEFAULT; +RESET SLAVE ALL; diff --git a/mysql-test/suite/sys_vars/r/debug_sync_basic.result b/mysql-test/suite/sys_vars/r/debug_sync_basic.result index 11506cac2c228..f0b69b8eb94ed 100644 --- a/mysql-test/suite/sys_vars/r/debug_sync_basic.result +++ b/mysql-test/suite/sys_vars/r/debug_sync_basic.result @@ -19,3 +19,8 @@ set @@session.debug_sync=1.1; ERROR 42000: Incorrect argument type to variable 'debug_sync' set @@session.debug_sync=1e1; ERROR 42000: Incorrect argument type to variable 'debug_sync' +set @@session.debug_sync='now SIGNAL ü'; +select @@session.debug_sync, charset(@@session.debug_sync); +@@session.debug_sync charset(@@session.debug_sync) +ON - current signals: 'ü' utf8mb3 +set @@session.debug_sync=reset; diff --git a/mysql-test/suite/sys_vars/r/default_master_connection_basic.result b/mysql-test/suite/sys_vars/r/default_master_connection_basic.result index 2d80241d5ca3d..255de938d7a51 100644 --- a/mysql-test/suite/sys_vars/r/default_master_connection_basic.result +++ b/mysql-test/suite/sys_vars/r/default_master_connection_basic.result @@ -27,6 +27,11 @@ SET @@session.default_master_connection = '1234-5678'; SELECT @@session.default_master_connection; @@session.default_master_connection 1234-5678 +SET @@session.default_master_connection = 'maître'; +SELECT @@session.default_master_connection , +CHARSET(@@session.default_master_connection); +@@session.default_master_connection CHARSET(@@session.default_master_connection) +maître utf8mb3 SET @@session.default_master_connection = '@!*/"'; SELECT @@session.default_master_connection; @@session.default_master_connection diff --git a/mysql-test/suite/sys_vars/t/debug_sync_basic.test b/mysql-test/suite/sys_vars/t/debug_sync_basic.test index c2c4df95c32e0..85b535e2cf2e7 100644 --- a/mysql-test/suite/sys_vars/t/debug_sync_basic.test +++ b/mysql-test/suite/sys_vars/t/debug_sync_basic.test @@ -1,3 +1,4 @@ +# Note: This file is in Latin1 (Windows-1252) encoding per MTR convention. --source include/have_debug_sync.inc # # exists as session only @@ -19,3 +20,7 @@ set @@session.debug_sync=1.1; --error ER_WRONG_TYPE_FOR_VAR set @@session.debug_sync=1e1; +# MDEV-40270: string with a different character set (Latin1 here) +set @@session.debug_sync='now SIGNAL ü'; +select @@session.debug_sync, charset(@@session.debug_sync); +set @@session.debug_sync=reset; diff --git a/mysql-test/suite/sys_vars/t/default_master_connection_basic.test b/mysql-test/suite/sys_vars/t/default_master_connection_basic.test index ae91bc46e1af1..e9a9418db02f6 100644 --- a/mysql-test/suite/sys_vars/t/default_master_connection_basic.test +++ b/mysql-test/suite/sys_vars/t/default_master_connection_basic.test @@ -3,6 +3,8 @@ # Implemented in the scope of MDEV-253 # The variable is SESSION-only # +# Note: This file is in Latin1 (Windows-1252) encoding per MTR convention. +# --source include/not_embedded.inc @@ -47,10 +49,15 @@ SET @@session.default_master_connection = ''; SELECT @@session.default_master_connection; SET @@session.default_master_connection = '1234-5678'; SELECT @@session.default_master_connection; +# MDEV-40270: string with a different character set (Latin1 here) +SET @@session.default_master_connection = 'maître'; +SELECT @@session.default_master_connection , + CHARSET(@@session.default_master_connection); SET @@session.default_master_connection = '@!*/"'; SELECT @@session.default_master_connection; SET @@session.default_master_connection = REPEAT('a',191); SELECT @@session.default_master_connection; +# bareword string SET @@session.default_master_connection = master2; SELECT @@session.default_master_connection; diff --git a/sql/sys_vars.inl b/sql/sys_vars.inl index 20155acba8aaa..bf4c3cce1a794 100644 --- a/sql/sys_vars.inl +++ b/sql/sys_vars.inl @@ -864,6 +864,7 @@ public: SYSVAR_ASSERT(scope() == ONLY_SESSION) *const_cast(&show_val_type)= SHOW_LEX_STRING; } + /// Duplicate of Sys_var_charptr::do_string_check() with @ref max_length check bool do_check(THD *thd, set_var *var) override { char buff[STRING_BUFFER_USUAL_SIZE]; @@ -876,6 +877,17 @@ public: } else { + uint32 _offset; + char charset_buff[STRING_BUFFER_USUAL_SIZE]; + String charset_str(charset_buff, sizeof(charset_buff), str.charset()); + if (String::needs_conversion(res->length(), res->charset(), + charset_str.charset(), &_offset)) + { + uint _errors; + charset_str.copy(res->ptr(), res->length(), + res->charset(), charset_str.charset(), &_errors); + res= &charset_str; + } if (res->length() > max_length) { my_error(ER_WRONG_STRING_LENGTH, MYF(0), @@ -1760,20 +1772,13 @@ public: SYSVAR_ASSERT(scope() == ONLY_SESSION); option.var_type|= GET_STR; } + /// Sys_var_dbug::do_check() with fixed charset() bool do_check(THD *thd, set_var *var) override { - char buff[STRING_BUFFER_USUAL_SIZE]; - String str(buff, sizeof(buff), system_charset_info), *res; - - if (!(res=var->value->val_str(&str))) - var->save_result.string_value= empty_lex_str; - else - { - if (!thd->make_lex_string(&var->save_result.string_value, - res->ptr(), res->length())) - return true; - } - return false; + bool error= Sys_var_charptr::do_string_check(thd, var, system_charset_info); + if (!var->save_result.string_value.str) + var->save_result.string_value.str= const_cast(""); + return error; } bool session_update(THD *thd, set_var *var) override {