Message ID | 20180104140223.4649-1-zajec5@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [LEDE-DEV] libfstools: support file paths longer than 255 chars | expand |
Rafa?? Mi??ecki <zajec5@gmail.com> wrote: > From: Rafa?? Mi??ecki <rafal@milecki.pl> > 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> > --- > libfstools/overlay.c | 21 +++++++++++++++++---- > 1 file changed, 17 insertions(+), 4 deletions(-) > diff --git a/libfstools/overlay.c b/libfstools/overlay.c > index 8423a57..a7c4f02 100644 > --- a/libfstools/overlay.c > +++ b/libfstools/overlay.c > @@ -67,15 +67,28 @@ handle_rmdir(const char *dir) > void > foreachdir(const char *dir, int (*cb)(const char*)) > { > + static char *globdir; > + static size_t globdirlen; > 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 + 3 > globdirlen) { > + size_t len = dirlen + 3 + 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++) { You missed call to free(globdir); at end. And original source missing globfree(gl); after for (..) loop.
Hi,
> You missed call to free(globdir); at end.
the buffer pointed to be globdir is supposed to stay, to be reused by
later invocations of foreachdir(). It's kind of a lazily initialized
global scratch buffer to construct intermediate path strings.
Good catch on the globfree() though, the way it is (not) implemented
right now seems to lead to some quite significant memory leaking,
especially when traversing deep and large directory structures.
~ Jo
diff --git a/libfstools/overlay.c b/libfstools/overlay.c index 8423a57..a7c4f02 100644 --- a/libfstools/overlay.c +++ b/libfstools/overlay.c @@ -67,15 +67,28 @@ handle_rmdir(const char *dir) void foreachdir(const char *dir, int (*cb)(const char*)) { + static char *globdir; + static size_t globdirlen; 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 + 3 > globdirlen) { + size_t len = dirlen + 3 + 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++) {