From 2a6bd9769d8eca95d63365bc8131b2ebc88294e6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 12 Jan 2021 22:31:35 -0800 Subject: [PATCH 3/3] glob: use scratch_buffer for glob_in_dir GLOBPAT_NONE This is an alternative implementation of a patch for glibc proposed by Adhemerval Zanella in: https://sourceware.org/pipermail/libc-alpha/2021-January/121347.html * lib/glob.c (glob_in_dir): Replace DIRECTORY arg with GLOBBUG + DIRLEN args, to make it easy to append to it. All callers changed. --- ChangeLog | 8 ++++++++ lib/glob.c | 41 +++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0a168e7b..2cab81b60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2021-01-12 Paul Eggert + glob: use scratch_buffer for glob_in_dir GLOBPAT_NONE + This is an alternative implementation of a patch for glibc + proposed by Adhemerval Zanella in: + https://sourceware.org/pipermail/libc-alpha/2021-January/121347.html + * lib/glob.c (glob_in_dir): Replace DIRECTORY arg with GLOBBUG + + DIRLEN args, to make it easy to append to it. All callers + changed. + glob: use scratch_buffer for GLOB_BRACE This is an alternative implementation of a patch for glibc proposed by Adhemerval Zanella in: diff --git a/lib/glob.c b/lib/glob.c index 304baebf6..f3c229035 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -239,7 +239,8 @@ glob_use_alloca (size_t alloca_used, size_t len) static int glob_buf (char const *, int, int (*) (char const *, int), glob_t *, struct scratch_buffer *); -static int glob_in_dir (const char *pattern, const char *directory, +static int glob_in_dir (const char *pattern, + struct scratch_buffer *globbuf, size_t dirlen, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used); static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL; @@ -884,7 +885,9 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), size_t old_pathc; old_pathc = pglob->gl_pathc; - status = glob_in_dir (filename, dirs.gl_pathv[i], + size_t dirs_i_len = strlen (dirs.gl_pathv[i]); + scratch_string (globbuf, dirs.gl_pathv[i], dirs_i_len); + status = glob_in_dir (filename, globbuf, dirs_i_len, ((flags | GLOB_APPEND) & ~(GLOB_NOCHECK | GLOB_NOMAGIC)), errfunc, pglob, alloca_used); @@ -989,7 +992,7 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), } if (dirname_modified) flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); - status = glob_in_dir (filename, dirname, flags, errfunc, pglob, + status = glob_in_dir (filename, globbuf, dirlen, flags, errfunc, pglob, alloca_used); if (status != 0) { @@ -1128,15 +1131,16 @@ prefix_array (const char *dirname, char **array, size_t n) } /* Like 'glob', but PATTERN is a final pathname component, - and matches are searched for in DIRECTORY. + and matches are searched for in the directory name in GLOBBUF. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. The GLOB_APPEND flag is assumed to be set (always appends). */ static int -glob_in_dir (const char *pattern, const char *directory, int flags, +glob_in_dir (const char *pattern, struct scratch_buffer *globbuf, + size_t dirlen, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used) { - size_t dirlen = strlen (directory); + char *directory = globbuf->data; void *stream = NULL; # define GLOBNAMES_MEMBERS(nnames) \ struct globnames *next; size_t count; char *name[nnames]; @@ -1169,31 +1173,20 @@ glob_in_dir (const char *pattern, const char *directory, int flags, else if (meta == GLOBPAT_NONE) { size_t patlen = strlen (pattern); - size_t fullsize; - bool alloca_fullname - = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize) - && glob_use_alloca (alloca_used, fullsize)); - char *fullname; - if (alloca_fullname) - fullname = alloca_account (fullsize, alloca_used); - else + while (globbuf->length - dirlen < patlen + 2) { - fullname = malloc (fullsize); - if (fullname == NULL) + if (!scratch_buffer_grow_preserve (globbuf)) return GLOB_NOSPACE; + directory = globbuf->data; } - - mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), - "/", 1), - pattern, patlen + 1); - if (glob_lstat (pglob, flags, fullname) == 0 + directory[dirlen] = '/'; + strcpy (directory + dirlen + 1, pattern); + if (glob_lstat (pglob, flags, directory) == 0 || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; - - if (__glibc_unlikely (!alloca_fullname)) - free (fullname); + directory[dirlen] = '\0'; } else { -- 2.27.0