From eaaf408c6dce7108a4ab47c9fad5009dda64bc04 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 12 Jan 2021 20:59:38 -0800 Subject: [PATCH 2/3] glob: use scratch_buffer for GLOB_BRACE This is an alternative implementation of a patch for glibc proposed by Adhemerval Zanella in: https://sourceware.org/pipermail/libc-alpha/2021-January/121345.html * lib/glob.c (glob_buf): Calculate pattern length at start. Use GLOBBUF for temporaries when analyzing brace expressions. --- ChangeLog | 7 +++++++ lib/glob.c | 40 +++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf235ce49..e0a168e7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2021-01-12 Paul Eggert + glob: use scratch_buffer for GLOB_BRACE + This is an alternative implementation of a patch for glibc + proposed by Adhemerval Zanella in: + https://sourceware.org/pipermail/libc-alpha/2021-January/121345.html + * lib/glob.c (glob_buf): Calculate pattern length at start. + Use GLOBBUF for temporaries when analyzing brace expressions. + glob: use scratch_buffer for internal glob dirname 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 44d2fdd5f..304baebf6 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -342,7 +342,8 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), /* POSIX requires all slashes to be matched. This means that with a trailing slash we must match only directories. */ - if (pattern[0] && pattern[strlen (pattern) - 1] == '/') + size_t pattern_len = strlen (pattern); + if (pattern_len != 0 && pattern[pattern_len - 1] == '/') flags |= GLOB_ONLYDIR; if (!(flags & GLOB_DOOFFS)) @@ -409,16 +410,13 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), const char *rest; size_t rest_len; char *onealt; - size_t pattern_len = strlen (pattern) - 1; - int alloca_onealt = glob_use_alloca (alloca_used, pattern_len); - if (alloca_onealt) - onealt = alloca_account (pattern_len, alloca_used); - else - { - onealt = malloc (pattern_len); - if (onealt == NULL) - return GLOB_NOSPACE; - } + + /* Allocate room for the pattern with any sub-pattern + subtituted for the brace expression. For simplicity, use + the pattern length; this is more than enough room. */ + if (!scratch_buffer_set_array_size (globbuf, pattern_len, 1)) + return GLOB_NOSPACE; + onealt = globbuf->data; /* We know the prefix for all sub-patterns. */ alt_start = mempcpy (onealt, pattern, begin - pattern); @@ -429,9 +427,6 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), if (next == NULL) { /* It is an invalid expression. */ - illegal_brace: - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); flags &= ~GLOB_BRACE; goto no_brace; } @@ -442,12 +437,16 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), { rest = next_brace_sub (rest + 1, flags); if (rest == NULL) - /* It is an illegal expression. */ - goto illegal_brace; + { + /* It is an invalid expression. */ + flags &= ~GLOB_BRACE; + goto no_brace; + } } /* Please note that we now can be sure the brace expression is well-formed. */ - rest_len = strlen (++rest) + 1; + rest_len = pattern + pattern_len - rest; + rest++; /* We have a brace expression. BEGIN points to the opening {, NEXT points past the terminator of the first element, and END @@ -472,8 +471,6 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); if (!(flags & GLOB_APPEND)) { globfree (pglob); @@ -491,9 +488,6 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), assert (next != NULL); } - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); - if (pglob->gl_pathc != firstc) /* We found some entries. */ return 0; @@ -524,7 +518,7 @@ glob_buf (const char *pattern, int flags, int (*errfunc) (const char *, int), case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { - dirlen = strlen (pattern); + dirlen = pattern_len; dirname = scratch_string (globbuf, pattern, dirlen); if (dirname == NULL) return GLOB_NOSPACE; -- 2.27.0