Commit ef5f757a authored by iggy@recycle.(none)'s avatar iggy@recycle.(none)

Bug#22807 mysql_upgrade fails when called with a basedir-path containing spaces

- Create space safe strings for system() calls in mysql_upgrade.exe
parent 8a746fc0
......@@ -461,7 +461,12 @@ int main(int argc, char **argv)
load_defaults("my", load_default_groups, &argc, &argv);
if (handle_options(&argc, &argv, my_long_options, get_one_option))
/*
Must init_dynamic_string before handle_options because string is freed
at error label.
*/
if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN) ||
handle_options(&argc, &argv, my_long_options, get_one_option))
{
ret= 1;
goto error;
......@@ -469,11 +474,6 @@ int main(int argc, char **argv)
if (tty_password)
opt_password= get_tty_password(NullS);
if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN))
{
ret= 1;
goto error;
}
if (!basedir)
{
my_getwd(path, sizeof(path), MYF(0));
......@@ -556,17 +556,34 @@ int main(int argc, char **argv)
goto error;
}
else
dynstr_set(&cmdline, path);
{
#ifdef __WIN__
/* Windows requires an extra pair of quotes around the entire string. */
dynstr_set(&cmdline, "\"");
#else
dynstr_set(&cmdline, "");
#endif /* __WIN__ */
dynstr_append_os_quoted(&cmdline, path, NullS);
}
if (defaults_to_use)
{
dynstr_append(&cmdline, " --defaults-extra-file=");
dynstr_append(&cmdline, defaults_to_use);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--defaults-extra-file=",
defaults_to_use, NullS);
}
dynstr_append(&cmdline, " --check-upgrade --all-databases"
" --auto-repair --user=");
dynstr_append(&cmdline, user);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--check-upgrade", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--all-databases", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--auto-repair", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--user=", user, NullS);
#ifdef __WIN__
dynstr_append(&cmdline, "\"");
#endif /* __WIN__ */
if (opt_verbose)
printf("Running %s\n", cmdline.str);
......@@ -595,7 +612,15 @@ fix_priv_tables:
goto error;
}
else
dynstr_set(&cmdline, path);
{
#ifdef __WIN__
/* Windows requires an extra pair of quotes around the entire string. */
dynstr_set(&cmdline, "\"");
#else
dynstr_set(&cmdline, "");
#endif /* __WIN__ */
dynstr_append_os_quoted(&cmdline, path, NullS);
}
if (find_file(MYSQL_FIX_PRIV_TABLES_NAME, basedir, MYF(0),
path, sizeof(path),
......@@ -617,13 +642,25 @@ fix_priv_tables:
if (defaults_to_use)
{
dynstr_append(&cmdline, " --defaults-extra-file=");
dynstr_append(&cmdline, defaults_to_use);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--defaults-extra-file=",
defaults_to_use, NullS);
}
dynstr_append(&cmdline, " --force --no-auto-rehash --batch --user=");
dynstr_append(&cmdline, user);
dynstr_append(&cmdline, " mysql < ");
dynstr_append(&cmdline, script_line);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--force", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--no-auto-rehash", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--batch", NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--user=", user, NullS);
dynstr_append(&cmdline, " ");
dynstr_append_os_quoted(&cmdline, "--database=mysql", NullS);
dynstr_append(&cmdline, " < ");
dynstr_append_os_quoted(&cmdline, script_line, NullS);
#ifdef __WIN__
dynstr_append(&cmdline, "\"");
#endif /* __WIN__ */
if (opt_verbose)
printf("Running %s\n", cmdline.str);
......
......@@ -781,6 +781,8 @@ extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
uint length);
extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append,
...);
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
extern void dynstr_free(DYNAMIC_STRING *str);
......
......@@ -116,6 +116,58 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
}
/** Concatenates any number of strings, escapes any OS quote in the result then
* surround the whole affair in another set of quotes which is finally appended
* to specified DYNAMIC_STRING. This function is especially useful when
* building strings to be executed with the system() function.
* @param str Dynamic String which will have addtional strings appended.
* @param append String to be appended.
* @param ... Optional. Additional string(s) to be appended.
*
* @note The final argument in the list must be NullS even if no additional
* options are passed.
*
* @return True = Success.
*/
my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
{
#ifdef __WIN__
char quote_str[]= "\"";
#else
char quote_str[]= "\'";
#endif /* __WIN__ */
my_bool ret= TRUE;
va_list dirty_text;
ret&= dynstr_append(str, quote_str); /* Leading quote */
va_start(dirty_text,append);
while (append != NullS)
{
char *cur_pos= append;
char *next_pos= cur_pos;
/* Search for quote in each string and replace with escaped quote */
while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')
{
char *tmp_buff= my_malloc((next_pos - cur_pos) + 1, MYF(MY_ZEROFILL));
strnmov(tmp_buff, cur_pos, (next_pos - cur_pos));
ret&= dynstr_append(str, tmp_buff);
my_free((gptr)tmp_buff, MYF(0));
ret&= dynstr_append(str ,"\\");
ret&= dynstr_append(str, quote_str);
cur_pos= next_pos + 1;
}
ret&= dynstr_append(str, cur_pos);
append= va_arg(dirty_text, char *);
}
va_end(dirty_text);
ret&= dynstr_append(str, quote_str); /* Trailing quote */
return ret;
}
void dynstr_free(DYNAMIC_STRING *str)
{
if (str->str)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment