bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] posix: if glob has a trailing slash match directories only.


From: Dmitry Goncharov
Subject: Re: [PATCH] posix: if glob has a trailing slash match directories only.
Date: Thu, 30 Nov 2017 00:01:19 -0500
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue, Nov 28, 2017 at 02:04:53PM -0800, Jonathan Nieder wrote:
> 
> What should happen in the DT_LNK case?  Should the same logic trip for
> it as well so we can distinguish between a symlink to a directory and
> other symlinks?
> 

The filesystems that i tested on all return DT_UNKNOWN for a symlink or
hardlink. Even when they return proper type for a file or directory.
However, if the filesystem ever sets type to DT_LNK glob needs to treat it like
DT_UNKNOWN.

regards, Dmitry

diff --git a/ChangeLog b/ChangeLog
index ffeb208132..fb76fc1415 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-28  Dmitry Goncharov  <address@hidden>
+
+       [BZ #22513]
+       * posix/glob.c (glob_in_dir): Make pattern with a trailing slash
+       match directores only.
+       * posix/globtest.sh: Add tests.
+
 2017-11-13  Florian Weimer  <address@hidden>
 
        * support/next_to_fault.h, support/next_to_fault.c: New files.
diff --git a/posix/glob.c b/posix/glob.c
index cb39779d07..47e67907cd 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -1342,7 +1342,33 @@ 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;
+                 case DT_DIR: break;
+                 case DT_LNK: case DT_UNKNOWN:
+                 {
+                   int dir;
+                   size_t namlen = strlen (d.name);
+                   size_t fullsize;
+                   bool alloca_fullname
+                     = (! size_add_wrapv (dirlen + 1, namlen + 1, &fullsize)
+                        && glob_use_alloca (alloca_used, fullsize));
+                   char *fullname;
+                   if (alloca_fullname)
+                     fullname = alloca_account (fullsize, alloca_used);
+                   else
+                     {
+                       fullname = malloc (fullsize);
+                       if (fullname == NULL)
+                         return GLOB_NOSPACE;
+                     }
+                   mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
+                                     "/", 1),
+                            d.name, namlen + 1);
+                   dir = is_dir (fullname, flags, pglob);
+                   if (__glibc_unlikely (!alloca_fullname))
+                     free (fullname);
+                   if (dir)
+                     break;
+                 }
                  default: continue;
                  }
 
diff --git a/posix/globtest.sh b/posix/globtest.sh
index 73f7ae31cc..4a062ea507 100755
--- a/posix/globtest.sh
+++ b/posix/globtest.sh
@@ -43,13 +43,22 @@ export LC_ALL
 
 # Create the arena
 testdir=${common_objpfx}posix/globtest-dir
+testdir2=${common_objpfx}posix/globtest-dir2
 testout=${common_objpfx}posix/globtest-out
 rm -rf $testdir $testout
 mkdir $testdir
+mkdir $testdir2
+mkdir $testdir2/hello1d
+ln -s $testdir2/hello1d $testdir2/hello1ds
+mkdir $testdir2/hello2d
+echo 1 > $testdir2/hello1f
+ln -s $testdir2/hello1f $testdir2/hello1fs
+echo 2 > $testdir2/hello2f
+ln $testdir2/hello2f $testdir2/hello2fl
 
 cleanup() {
     chmod 777 $testdir/noread
-    rm -fr $testdir $testout
+    rm -fr $testdir $testdir2 $testout
 }
 
 trap cleanup 0 HUP INT QUIT TERM
@@ -815,6 +824,45 @@ if test $failed -ne 0; then
   result=1
 fi
 
+# Test that if the specified glob ends with a slash then only directories are
+# matched.
+# First run with the glob that has no slash to demonstrate presence of a slash
+# makes a difference.
+failed=0
+${test_program_prefix} \
+${common_objpfx}posix/globtest "$testdir2" "hello*" |
+sort > $testout
+cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
+`hello1d'
+`hello1ds'
+`hello1f'
+`hello1fs'
+`hello2d'
+`hello2f'
+`hello2fl'
+EOF
+
+if test $failed -ne 0; then
+  echo "pattern+meta test failed" >> $logfile
+  result=1
+fi
+
+# The same pattern+meta test with a slash this time.
+failed=0
+${test_program_prefix} \
+${common_objpfx}posix/globtest "$testdir2" "hello*/" |
+sort > $testout
+cat <<"EOF" | $CMP - $testout >> $logfile || failed=1
+`hello1d/'
+`hello1ds/'
+`hello2d/'
+EOF
+
+if test $failed -ne 0; then
+  echo "pattern+meta+slash test failed" >> $logfile
+  result=1
+fi
+
 if test $result -eq 0; then
     echo "All OK." > $logfile
 fi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]