X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/bc267e0f572591ec3e31f919d15041baa74bfae1..6db1db54883508cd572e24f93e7bee14e286967d:/util.c diff --git a/util.c b/util.c index a4a08e7c..2afb63ec 100644 --- a/util.c +++ b/util.c @@ -582,26 +582,19 @@ static inline void call_glob_match(const char *name, int len, int from_glob, } else use_buf = glob.arg_buf; - if (from_glob || arg) { + if (from_glob || (arg && len)) { STRUCT_STAT st; int is_dir; - if (do_stat(glob.arg_buf, &st) != 0) { - if (from_glob) - return; - is_dir = 0; - } else { - is_dir = S_ISDIR(st.st_mode) != 0; - if (arg && !is_dir) - return; - } + if (do_stat(glob.arg_buf, &st) != 0) + return; + is_dir = S_ISDIR(st.st_mode) != 0; + if (arg && !is_dir) + return; if (daemon_filter_list.head - && check_filter(&daemon_filter_list, use_buf, is_dir) < 0) { - if (from_glob) - return; - arg = NULL; - } + && check_filter(&daemon_filter_list, FLOG, use_buf, is_dir) < 0) + return; } if (arg) { @@ -950,7 +943,7 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth, /* Like chdir(), but it keeps track of the current directory (in the * global "curr_dir"), and ensures that the path size doesn't overflow. * Also cleans the path using the clean_fname() function. */ -int push_dir(const char *dir, int set_path_only) +int change_dir(const char *dir, int set_path_only) { static int initialised; unsigned int len; @@ -968,21 +961,26 @@ int push_dir(const char *dir, int set_path_only) if (len == 1 && *dir == '.') return 1; - if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir) { - errno = ENAMETOOLONG; - return 0; - } - - if (!set_path_only && chdir(dir)) - return 0; - if (*dir == '/') { + if (len >= sizeof curr_dir) { + errno = ENAMETOOLONG; + return 0; + } + if (!set_path_only && chdir(dir)) + return 0; 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; + if (curr_dir_len + 1 + len >= sizeof curr_dir) { + errno = ENAMETOOLONG; + return 0; + } + curr_dir[curr_dir_len] = '/'; + memcpy(curr_dir + curr_dir_len + 1, dir, len + 1); + + if (!set_path_only && chdir(curr_dir)) { + curr_dir[curr_dir_len] = '\0'; + return 0; + } } curr_dir_len = clean_fname(curr_dir, CFN_COLLAPSE_DOT_DOT_DIRS); @@ -993,28 +991,7 @@ int push_dir(const char *dir, int set_path_only) } if (verbose >= 5 && !set_path_only) - rprintf(FINFO, "[%s] push_dir(%s)\n", who_am_i(), curr_dir); - - return 1; -} - -/** - * Reverse a push_dir() call. You must pass in an absolute path - * that was copied from a prior value of "curr_dir". - **/ -int pop_dir(const char *dir) -{ - if (chdir(dir)) - return 0; - - curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir); - if (curr_dir_len >= sizeof curr_dir) - curr_dir_len = sizeof curr_dir - 1; - if (sanitize_paths) - curr_dir_depth = count_dir_elements(curr_dir + module_dirlen); - - if (verbose >= 5) - rprintf(FINFO, "[%s] pop_dir(%s)\n", who_am_i(), curr_dir); + rprintf(FINFO, "[%s] change_dir(%s)\n", who_am_i(), curr_dir); return 1; } @@ -1077,10 +1054,10 @@ char *partial_dir_fname(const char *fname) if (daemon_filter_list.head) { t = strrchr(partial_fname, '/'); *t = '\0'; - if (check_filter(&daemon_filter_list, partial_fname, 1) < 0) + if (check_filter(&daemon_filter_list, FLOG, partial_fname, 1) < 0) return NULL; *t = '/'; - if (check_filter(&daemon_filter_list, partial_fname, 0) < 0) + if (check_filter(&daemon_filter_list, FLOG, partial_fname, 0) < 0) return NULL; } @@ -1352,7 +1329,7 @@ void *_new_array(unsigned long num, unsigned int size, int use_calloc) return use_calloc ? calloc(num, size) : malloc(num * size); } -void *_realloc_array(void *ptr, unsigned int size, unsigned long num) +void *_realloc_array(void *ptr, unsigned int size, size_t num) { if (num >= MALLOC_MAX/size) return NULL; @@ -1573,7 +1550,10 @@ void *expand_item_list(item_list *lp, size_t item_size, new_size += incr; else new_size *= 2; - new_ptr = realloc_array(lp->items, char, new_size * item_size); + if (new_size < lp->malloced) + overflow_exit("expand_item_list"); + /* Using _realloc_array() lets us pass the size, not a type. */ + new_ptr = _realloc_array(lp->items, item_size, new_size); if (verbose >= 4) { rprintf(FINFO, "[%s] expand %s to %.0f bytes, did%s move\n", who_am_i(), desc, (double)new_size * item_size,