summaryrefslogtreecommitdiff
path: root/server-tools
diff options
context:
space:
mode:
authorunknown <petr/cps@outpost.site>2006-11-22 19:07:05 +0300
committerunknown <petr/cps@outpost.site>2006-11-22 19:07:05 +0300
commit779d2f16ecd31c6ff3ebe0a5b39acb5020b3a08c (patch)
tree5d49a78a59cbb7c9841ff7b9e26c0c44ec765b41 /server-tools
parent5856b836de776b8740dba4ebafc4d89d87f6963c (diff)
downloadmariadb-git-779d2f16ecd31c6ff3ebe0a5b39acb5020b3a08c.tar.gz
Fix Bug #22242 Instance Manager: option-parsing errors
There was a memory overrun, which resulted in safemalloc errors. Recommit with post-review fixes. server-tools/instance-manager/instance_options.cc: Memory was overrun here: convert_dirname() adds a slash to the end of the string. Then it was removed (with end[-1]=0), but the overrun still happened, which caused sefemalloc to complain. The problem stemed from the fact that we converted the path to the binary, not to the directory. Now we first truncate the path and then convert the name of the directory, where the binary resides. E.g. Suppose that IM got an option --mysqld-path='/usr/local/bin/mysqld'. Then convert dirname was called. This routine takes a path to the dir (not binary!) and converts it for usage under particular OS. And at least for *nixes it *always* adds slash. E.g. for the path above convert_dirname() will result in path: '/usr/local/bin/mysqld/' Note the last slash. The fix is to convert the path to the dir where the binary resides: /usr/local/bin/. Then we put back the binary name.
Diffstat (limited to 'server-tools')
-rw-r--r--server-tools/instance-manager/instance_options.cc61
1 files changed, 55 insertions, 6 deletions
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 00da6660703..394a303cc6a 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -59,6 +59,29 @@ static inline int create_mysqld_command(Buffer *buf,
return 1;
}
+static inline bool is_path_separator(char ch)
+{
+#if defined(__WIN__) || defined(__NETWARE__)
+ /* On windows and netware more delimiters are possible */
+ return ch == FN_LIBCHAR || ch == FN_DEVCHAR || ch == '/';
+#else
+ return ch == FN_LIBCHAR; /* Unixes */
+#endif
+}
+
+
+static char *find_last_path_separator(char *path, uint length)
+{
+ while (length)
+ {
+ if (is_path_separator(path[length]))
+ return path + length;
+ length--;
+ }
+ return NULL; /* No path separator found */
+}
+
+
bool Instance_options::is_option_im_specific(const char *option_name)
{
@@ -420,21 +443,47 @@ int Instance_options::complete_initialization(const char *default_path)
int arg_idx;
const char *tmp;
char *end;
+ char bin_name_firstchar;
if (!mysqld_path.str)
{
- // Need one extra byte, as convert_dirname() adds a slash at the end.
- if (!(mysqld_path.str= alloc_root(&alloc, strlen(default_path) + 2)))
+ /*
+ Need to copy the path to allocated memory, as convert_dirname() might
+ need to change it
+ */
+ if (!(mysqld_path.str= alloc_root(&alloc, strlen(default_path) + 1)))
goto err;
strcpy(mysqld_path.str, default_path);
}
- // it's safe to cast this to char* since this is a buffer we are allocating
- end= convert_dirname((char*)mysqld_path.str, mysqld_path.str, NullS);
- end[-1]= 0;
-
mysqld_path.length= strlen(mysqld_path.str);
+ /*
+ If we found path with no slashes (end == NULL), we should not call
+ convert_dirname() at all. As we have got relative path to the binary.
+ That is, user supposes that mysqld resides in the same dir as
+ mysqlmanager.
+ */
+ if ((end= find_last_path_separator(mysqld_path.str, mysqld_path.length)))
+ {
+ bin_name_firstchar= end[1];
+
+ /*
+ Below we will conver the path to mysqld in the case, it was given
+ in a format of another OS (e.g. uses '/' instead of '\' etc).
+ Here we strip the path to get rid of the binary name ("mysqld"),
+ we do it by removing first letter of the binary name (e.g. 'm'
+ in "mysqld"). Later we put it back.
+ */
+ end[1]= 0;
+
+ /* convert dirname to the format of current OS */
+ convert_dirname((char*)mysqld_path.str, mysqld_path.str, NullS);
+
+ /* put back the first character of the binary name*/
+ end[1]= bin_name_firstchar;
+ }
+
if (mysqld_port)
mysqld_port_val= atoi(mysqld_port);