summaryrefslogtreecommitdiff
path: root/client/mysql.cc
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2021-11-26 18:41:35 +0100
committerSergei Golubchik <serg@mariadb.org>2021-12-15 19:13:57 +0100
commit71966c7306d6ae24bc052d5433e6d97cc81a436a (patch)
treea922986274d3bdd70f3640c27a5b251f337facc3 /client/mysql.cc
parent9ea83f7fbd6fe3f76ba0304851cfe96cd4cc1071 (diff)
downloadmariadb-git-71966c7306d6ae24bc052d5433e6d97cc81a436a.tar.gz
MDEV-26713 allow users with non-UTF8 passwords to login after upgrade.preview-10.8-MDEV-26713-windows-i18-support
Translate username, password and database from UTF8 into desired charset, if non-auto default-character-set was used, on Windows10 1903 This change is implemented only in the command line client, and mainly to allow users with non-UTF8 passwords to login. The user is supposed to use the same charset that was used during setting password (usually, console CP if used in CLI) Add a test to document the behavior.
Diffstat (limited to 'client/mysql.cc')
-rw-r--r--client/mysql.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index d15a5ebdb40..49e6d29e964 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1442,6 +1442,46 @@ sig_handler mysql_end(int sig)
exit(status.exit_status);
}
+#ifdef _WIN32
+#define CNV_BUFSIZE 1024
+
+/**
+ Convert user,database,and password to requested charset.
+
+ This is done in the single case when user connects with non-UTF8
+ default-character-set, on UTF8 capable Windows.
+
+ User, password, and database are UTF8 encoded, prior to the function,
+ this needs to be fixed, in case they contain non-ASCIIs.
+
+ Mostly a workaround, to allow existng users with non-ASCII password
+ to survive upgrade without losing connectivity.
+*/
+static void maybe_convert_charset(const char **user, const char **password,
+ const char **database, const char *csname)
+{
+ if (GetACP() != CP_UTF8 || !strncmp(csname, "utf8", 4))
+ return;
+ static char bufs[3][CNV_BUFSIZE];
+ const char **from[]= {user, password, database};
+ CHARSET_INFO *cs= get_charset_by_csname(csname, MY_CS_PRIMARY,
+ MYF(MY_UTF8_IS_UTF8MB3 | MY_WME));
+ if (!cs)
+ return;
+ for (int i= 0; i < 3; i++)
+ {
+ const char *str= *from[i];
+ if (!str)
+ continue;
+ uint errors;
+ uint len= my_convert(bufs[i], CNV_BUFSIZE, cs, str, (uint32) strlen(str),
+ &my_charset_utf8mb4_bin, &errors);
+ bufs[i][len]= 0;
+ *from[i]= bufs[i];
+ }
+}
+#endif
+
/*
set connection-specific options and call mysql_real_connect
*/
@@ -1473,6 +1513,10 @@ static bool do_connect(MYSQL *mysql, const char *host, const char *user,
mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
"program_name", "mysql");
+#ifdef _WIN32
+ maybe_convert_charset(&user, &password, &database,default_charset);
+#endif
+
return mysql_real_connect(mysql, host, user, password, database,
opt_mysql_port, opt_mysql_unix_port, flags);
}