diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2018-01-04 14:58:18 +0100 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2018-01-05 14:48:59 +0100 |
commit | 37762ff488752c1686b359816aec75831b49c55f (patch) | |
tree | 1ac97804d3fec36ec7b8561d5cf81e145eef7910 | |
parent | bdcb075fafdac0bfe3207c23f64acd58432bad86 (diff) | |
download | fstools-37762ff488752c1686b359816aec75831b49c55f.tar.gz |
libfstools: support file paths longer than 255 chars
Alloc globdir buffer dynamically and simply use realloc when needed.
This fixes e.g. segmentation fault in jffs2reset due to an infinite
recurrency when dealing with longs paths.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-rw-r--r-- | libfstools/overlay.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/libfstools/overlay.c b/libfstools/overlay.c index 5a49da2..6024586 100644 --- a/libfstools/overlay.c +++ b/libfstools/overlay.c @@ -67,15 +67,29 @@ handle_rmdir(const char *dir) void foreachdir(const char *dir, int (*cb)(const char*)) { + static char *globdir = NULL; + static size_t globdirlen = 0; struct stat s = { 0 }; - char globdir[256]; + size_t dirlen = strlen(dir); glob_t gl; int j; - if (dir[strlen(dir) - 1] == '/') - snprintf(globdir, 256, "%s*", dir); + if (dirlen + sizeof("/*") > globdirlen) { + /* Alloc extra 256 B to avoid too many reallocs */ + size_t len = dirlen + sizeof("/*") + 256; + char *tmp; + + tmp = realloc(globdir, len); + if (!tmp) + return; + globdir = tmp; + globdirlen = len; + } + + if (dir[dirlen - 1] == '/') + sprintf(globdir, "%s*", dir); else - snprintf(globdir, 256, "%s/*", dir); /**/ + sprintf(globdir, "%s/*", dir); if (!glob(globdir, GLOB_NOESCAPE | GLOB_MARK | GLOB_ONLYDIR, NULL, &gl)) for (j = 0; j < gl.gl_pathc; j++) { |