From patchwork Wed Mar 30 21:55:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 52485 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8D8043870C27 for ; Wed, 30 Mar 2022 21:55:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8D8043870C27 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1648677356; bh=JGygVqzDQBY0MVpBVD8aodvJVHGrCb9BweB91w7e+dw=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=HgO6zU4vrA3oQbOyv/5thhbSn6Yie9YqFRSok/GhDS6ekqSVcLPjSfDH6Oi3USkMO PDPzbT35xFDHq/zi5l2ueuXP2rJT0NgfYbT9+gO7A/xqBnJ5ea6dns4ut+J4bm6V6J P5z6KB5+3uLcGSLFMUjmoSzmHVJLcoTCBMM7J/2o= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id C05763858C2D for ; Wed, 30 Mar 2022 21:55:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C05763858C2D Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-580-C5OjZ4I1Mv2IRjmXJpjvhA-1; Wed, 30 Mar 2022 17:55:32 -0400 X-MC-Unique: C5OjZ4I1Mv2IRjmXJpjvhA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 11E61811E7A for ; Wed, 30 Mar 2022 21:55:32 +0000 (UTC) Received: from greed.delorie.com (ovpn-112-4.rdu2.redhat.com [10.10.112.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F0C9840CF8E4 for ; Wed, 30 Mar 2022 21:55:31 +0000 (UTC) Received: from greed.delorie.com.redhat.com (localhost [127.0.0.1]) by greed.delorie.com (8.15.2/8.15.2) with ESMTP id 22ULtVlK086816 for ; Wed, 30 Mar 2022 17:55:31 -0400 Date: Wed, 30 Mar 2022 17:55:31 -0400 Message-Id: To: libc-alpha@sourceware.org Subject: posix/glob.c: update from gnulib X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: DJ Delorie via Libc-alpha From: DJ Delorie Reply-To: DJ Delorie Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Copied from gnulib/lib/glob.c in order to fix rhbz 1982608 Used config.h instead of libc-config.h The #ifdef around #define dirfd() was changed to #undef due to conflicts between glibc's internal and external definitions of dirfd(). This has been reported to gnulib. diff --git a/posix/glob.c b/posix/glob.c index a2b5aabada..19b876f9f0 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -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 #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 @@ -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; }