From 91eefc3f3a727fc629f936f5ceece974f55b8ad1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 4 Feb 2008 07:39:42 +0100 Subject: [PATCH] Fix initialization of configdir Windows code leaked memory (result of _fullpath()). POSIX code passed a null buffer to getcwd(), which is not portable, and failed to check for errors. --- src/lib/common/emp_config.c | 49 +++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/lib/common/emp_config.c b/src/lib/common/emp_config.c index 174886220..5366a399a 100644 --- a/src/lib/common/emp_config.c +++ b/src/lib/common/emp_config.c @@ -66,7 +66,7 @@ struct keymatch configkeys[] = { }; static struct keymatch *keylookup(char *key, struct keymatch tbl[]); -static void set_paths(char *); +static int set_paths(char *); /* * read in empire configuration @@ -150,7 +150,8 @@ emp_config(char *file) done: WORLD_X &= ~1; /* force even */ - set_paths(file); + if (set_paths(file) < 0) + return -1; return -errors; } @@ -170,43 +171,39 @@ keylookup(char *command, struct keymatch *tbl) return NULL; } -static void +static int set_paths(char *econfig) { - char *slash; - char *cwd = getcwd(NULL, 0); + char *p, *slash; #ifdef _WIN32 - /* normalize path separator to '\\', for easier searching: */ - econfig = _fullpath(NULL, econfig, 0); - slash = strrchr(econfig, '\\'); - configdir = malloc(slash - econfig + 1); - memcpy(configdir, econfig, slash - econfig); - configdir[slash - econfig] = 0; + p = _fullpath(NULL, econfig, 0); + slash = strrchr(p, '\\'); #else - if ((slash = strrchr(econfig, '/'))) { - configdir = malloc(slash - econfig + 1); - memcpy(configdir, econfig, slash - econfig); - configdir[slash - econfig] = 0; - } else - configdir = strdup(cwd); - - if (configdir[0] != '/') { - char *tmp = configdir; - size_t len = strlen(cwd); - - configdir = malloc(len + 1 + strlen(tmp) + 1); - sprintf(configdir, "%s/%s", cwd, tmp); - free(tmp); + char buf[1024]; + char *cwd; + + cwd = getcwd(buf, sizeof(buf)); + p = fnameat(econfig, cwd); + if (p[0] != '/') { + fprintf(stderr, "Can't get current working directory (%s)\n", + strerror(errno)); + return -1; } + if (p == econfig) + p = strdup(p); + slash = strrchr(p, '/'); #endif /* !_WIN32 */ + *slash = 0; + configdir = realloc(p, slash + 1 - configdir); + infodir = fnameat(infodir_conf, configdir); gamedir = fnameat(gamedir_conf, configdir); builtindir = fnameat(builtindir_conf, configdir); schedulefil = fnameat("schedule", configdir); - free(cwd); + return 0; } void -- 2.43.0