From 4af8fe4e789162a3aea497f2a8218bc49aecdb60 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Tue, 20 Jan 2004 17:46:29 +0000 Subject: [PATCH] - Changed push_dir() to not take a "save" arg and to return 1 or 0 for success or failure instead of a string pointer. The function also ensures that we don't overflow the curr_dir[] buffer. - Changed pop_dir() to not free() anything and to return 1 or 0 for success or failure. --- util.c | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/util.c b/util.c index fe81f2ad..bda3bc21 100644 --- a/util.c +++ b/util.c @@ -760,57 +760,61 @@ void sanitize_path(char *p, char *reldir) char curr_dir[MAXPATHLEN]; +unsigned int curr_dir_len; /** * Like chdir() but can be reversed with pop_dir() if @p save is set. * It is also much faster as it remembers where we have been. **/ -char *push_dir(char *dir, int save) +int push_dir(char *dir) { - char *ret = curr_dir; static int initialised; + unsigned int len; if (!initialised) { initialised = 1; getcwd(curr_dir, sizeof(curr_dir)-1); + curr_dir_len = strlen(curr_dir); } - if (!dir) return NULL; /* this call was probably just to initialize */ + if (!dir) /* this call was probably just to initialize */ + return 0; - if (chdir(dir)) return NULL; + len = strlen(dir); + if (len == 1 && *dir == '.') + return 1; - if (save) { - ret = strdup(curr_dir); - } + if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir) + return 0; + + if (chdir(dir)) + return 0; if (*dir == '/') { - strlcpy(curr_dir, dir, sizeof(curr_dir)); - } else if (dir[0] != '.' || dir[1] != '\0') { - strlcat(curr_dir,"/", sizeof(curr_dir)); - strlcat(curr_dir,dir, sizeof(curr_dir)); + memcpy(curr_dir, dir, len + 1); + curr_dir_len = len; + } else { + curr_dir[curr_dir_len++] = '/'; + memcpy(curr_dir + curr_dir_len, dir, len + 1); + curr_dir_len += len; } clean_fname(curr_dir); - return ret; + return 1; } /** Reverse a push_dir() call */ int pop_dir(char *dir) { - int ret; - - ret = chdir(dir); - if (ret) { - free(dir); - return ret; - } - - strlcpy(curr_dir, dir, sizeof(curr_dir)); + if (chdir(dir)) + return 0; - free(dir); + curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir); + if (curr_dir_len >= sizeof curr_dir) + curr_dir_len = sizeof curr_dir - 1; - return 0; + return 1; } /** -- 2.34.1