summaryrefslogtreecommitdiff
path: root/posix-glob.c-update-from-gnulib.patch
diff options
context:
space:
mode:
Diffstat (limited to 'posix-glob.c-update-from-gnulib.patch')
-rw-r--r--posix-glob.c-update-from-gnulib.patch195
1 files changed, 195 insertions, 0 deletions
diff --git a/posix-glob.c-update-from-gnulib.patch b/posix-glob.c-update-from-gnulib.patch
new file mode 100644
index 0000000..c15090a
--- /dev/null
+++ b/posix-glob.c-update-from-gnulib.patch
@@ -0,0 +1,195 @@
+From c66c92181ddbd82306537a608e8c0282587131de Mon Sep 17 00:00:00 2001
+From: DJ Delorie <dj@redhat.com>
+Date: Wed, 30 Mar 2022 17:44:02 -0400
+Subject: [PATCH] posix/glob.c: update from gnulib
+
+Copied from gnulib/lib/glob.c in order to fix rhbz 1982608
+Also fixes swbz 25659
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 7c477b57a31487eda516db02b9e04f22d1a6e6af)
+---
+ posix/glob.c | 70 +++++++++++++++++++++++++++------
+ sysdeps/unix/sysv/linux/glob64-time64.c | 1 +
+ 2 files changed, 59 insertions(+), 12 deletions(-)
+
+diff --git a/posix/glob.c b/posix/glob.c
+index 593a4c3..6af310a 100644
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -21,13 +21,14 @@
+ optimizes away the pattern == NULL test below. */
+ # define _GL_ARG_NONNULL(params)
+
+-# include <config.h>
++# include <libc-config.h>
+
+ #endif
+
+ #include <glob.h>
+
+ #include <errno.h>
++#include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdbool.h>
+@@ -56,6 +57,8 @@
+ # define sysconf(id) __sysconf (id)
+ # define closedir(dir) __closedir (dir)
+ # define opendir(name) __opendir (name)
++# undef dirfd
++# define dirfd(str) __dirfd (str)
+ # define readdir(str) __readdir64 (str)
+ # define getpwnam_r(name, bufp, buf, len, res) \
+ __getpwnam_r (name, bufp, buf, len, res)
+@@ -69,11 +72,8 @@
+ # ifndef GLOB_LSTAT
+ # define GLOB_LSTAT gl_lstat
+ # endif
+-# ifndef GLOB_STAT64
+-# define GLOB_STAT64 __stat64
+-# endif
+-# ifndef GLOB_LSTAT64
+-# define GLOB_LSTAT64 __lstat64
++# ifndef GLOB_FSTATAT64
++# define GLOB_FSTATAT64 __fstatat64
+ # endif
+ # include <shlib-compat.h>
+ #else /* !_LIBC */
+@@ -88,8 +88,7 @@
+ # define struct_stat struct stat
+ # define struct_stat64 struct stat
+ # define GLOB_LSTAT gl_lstat
+-# define GLOB_STAT64 stat
+-# define GLOB_LSTAT64 lstat
++# define GLOB_FSTATAT64 fstatat
+ #endif /* _LIBC */
+
+ #include <fnmatch.h>
+@@ -215,7 +214,8 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname)
+ } ust;
+ return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
+ ? pglob->GLOB_LSTAT (fullname, &ust.st)
+- : GLOB_LSTAT64 (fullname, &ust.st64));
++ : GLOB_FSTATAT64 (AT_FDCWD, fullname, &ust.st64,
++ AT_SYMLINK_NOFOLLOW));
+ }
+
+ /* Set *R = A + B. Return true if the answer is mathematically
+@@ -257,7 +257,8 @@ is_dir (char const *filename, int flags, glob_t const *pglob)
+ struct_stat64 st64;
+ return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
+ ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
+- : GLOB_STAT64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
++ : (GLOB_FSTATAT64 (AT_FDCWD, filename, &st64, 0) == 0
++ && S_ISDIR (st64.st_mode)));
+ }
+
+ /* Find the end of the sub-pattern in a brace expression. */
+@@ -747,6 +748,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
+ else
+ {
+ #ifndef WINDOWS32
++ /* Recognize ~user as a shorthand for the specified user's home
++ directory. */
+ char *end_name = strchr (dirname, '/');
+ char *user_name;
+ int malloc_user_name = 0;
+@@ -885,7 +888,22 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
+ }
+ scratch_buffer_free (&pwtmpbuf);
+ }
+-#endif /* !WINDOWS32 */
++#else /* WINDOWS32 */
++ /* On native Windows, access to a user's home directory
++ (via GetUserProfileDirectory) or to a user's environment
++ variables (via ExpandEnvironmentStringsForUser) requires
++ the credentials of the user. Therefore we cannot support
++ the ~user syntax on this platform.
++ Handling ~user specially (and treat it like plain ~) if
++ user is getenv ("USERNAME") would not be a good idea,
++ since it would make people think that ~user is supported
++ in general. */
++ if (flags & GLOB_TILDE_CHECK)
++ {
++ retval = GLOB_NOMATCH;
++ goto out;
++ }
++#endif /* WINDOWS32 */
+ }
+ }
+
+@@ -1266,6 +1284,8 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+ {
+ size_t dirlen = strlen (directory);
+ void *stream = NULL;
++ struct scratch_buffer s;
++ scratch_buffer_init (&s);
+ # define GLOBNAMES_MEMBERS(nnames) \
+ struct globnames *next; size_t count; char *name[nnames];
+ struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
+@@ -1337,6 +1357,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+ }
+ else
+ {
++ int dfd = dirfd (stream);
+ int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
+ | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
+ flags |= GLOB_MAGCHAR;
+@@ -1364,8 +1385,32 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+ if (flags & GLOB_ONLYDIR)
+ switch (readdir_result_type (d))
+ {
+- case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
+ default: continue;
++ case DT_DIR: break;
++ case DT_LNK: case DT_UNKNOWN:
++ /* The filesystem was too lazy to give us a hint,
++ so we have to do it the hard way. */
++ if (__glibc_unlikely (dfd < 0 || flags & GLOB_ALTDIRFUNC))
++ {
++ size_t namelen = strlen (d.name);
++ size_t need = dirlen + 1 + namelen + 1;
++ if (s.length < need
++ && !scratch_buffer_set_array_size (&s, need, 1))
++ goto memory_error;
++ char *p = mempcpy (s.data, directory, dirlen);
++ *p = '/';
++ p += p[-1] != '/';
++ memcpy (p, d.name, namelen + 1);
++ if (! is_dir (s.data, flags, pglob))
++ continue;
++ }
++ else
++ {
++ struct_stat64 st64;
++ if (! (GLOB_FSTATAT64 (dfd, d.name, &st64, 0) == 0
++ && S_ISDIR (st64.st_mode)))
++ continue;
++ }
+ }
+
+ if (fnmatch (pattern, d.name, fnm_flags) == 0)
+@@ -1497,5 +1542,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+ __set_errno (save);
+ }
+
++ scratch_buffer_free (&s);
+ return result;
+ }
+diff --git a/sysdeps/unix/sysv/linux/glob64-time64.c b/sysdeps/unix/sysv/linux/glob64-time64.c
+index a465f70..95efe4c 100644
+--- a/sysdeps/unix/sysv/linux/glob64-time64.c
++++ b/sysdeps/unix/sysv/linux/glob64-time64.c
+@@ -37,6 +37,7 @@
+ # define GLOB_LSTAT gl_lstat
+ # define GLOB_STAT64 __stat64_time64
+ # define GLOB_LSTAT64 __lstat64_time64
++# define GLOB_FSTATAT64 __fstatat64_time64
+
+ # define COMPILE_GLOB64 1
+
+--
+1.8.3.1
+