summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql_upgrade.c77
-rw-r--r--include/my_sys.h2
-rw-r--r--mysys/string.c52
3 files changed, 111 insertions, 20 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index e1372b2dbbd..15f105fd8fe 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -470,7 +470,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;
@@ -478,11 +483,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));
@@ -565,17 +565,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);
@@ -604,7 +621,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),
@@ -626,13 +651,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);
diff --git a/include/my_sys.h b/include/my_sys.h
index 77367c1f246..aa8cef1a25a 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -782,6 +782,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 my_bool dynstr_trunc(DYNAMIC_STRING *str, int n);
diff --git a/mysys/string.c b/mysys/string.c
index 86de7bfcf69..dd483e6da87 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -121,6 +121,58 @@ my_bool dynstr_trunc(DYNAMIC_STRING *str, int n)
return FALSE;
}
+/** 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)