https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=fde4eaa105912625b6a78fba79d1fc39ee0fd201

commit fde4eaa105912625b6a78fba79d1fc39ee0fd201
Author: Corinna Vinschen <[email protected]>
Date:   Sun Jan 6 14:29:53 2019 +0100

    Cygwin: path_conv: decouple pathconv_flags from path_types
    
    There's an unfortunate amalgamation of caller-provided pathconv_arg
    flags with path_types flags which in turn are mostly mount flags.
    
    This leads to a confusion of flag values in sylink_info::pflags and,
    in turn, in path_conv::path_flags.
    
    This patch decouples pathconv_flags from the other flags by making
    sure that a pathconv_flag is never copied into a variable used for
    path_types flags.  Also, remove PATH_NO_ACCESS_CHECK since it's
    not necessary.
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/path.cc | 19 +++++++++++--------
 winsup/cygwin/path.h  |  3 ++-
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index b039801..28b9666 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -80,7 +80,8 @@ struct symlink_info
   char contents[SYMLINK_MAX + 1];
   char *ext_here;
   int extn;
-  unsigned pflags;
+  unsigned pflags;     /* path flags, i.e. mount flags, special files, ... */
+  unsigned pc_flags;   /* Relevant flags from caller of path_conv */
   DWORD fileattr;
   int issymlink;
   bool ext_tacked_on;
@@ -735,9 +736,10 @@ path_conv::check (const char *src, unsigned opt,
 
          int symlen = 0;
 
-         for (unsigned pflags_or = opt & (PC_NO_ACCESS_CHECK | PC_KEEP_HANDLE);
+         /* Make sure to check certain flags on last component only. */
+         for (unsigned pc_flags = opt & (PC_NO_ACCESS_CHECK | PC_KEEP_HANDLE);
               ;
-              pflags_or = 0)
+              pc_flags = 0)
            {
              const suffix_info *suff;
              char *full_path;
@@ -764,7 +766,7 @@ path_conv::check (const char *src, unsigned opt,
              if (error)
                return;
 
-             sym.pflags |= pflags_or;
+             sym.pc_flags = pc_flags;
 
              if (!dev.exists ())
                {
@@ -1190,7 +1192,7 @@ path_conv::check (const char *src, unsigned opt,
                                  it will be figured out later by anything
                                  which cares about this. */
            }
-         /* If the FS has been found to have unrelibale inodes, note
+         /* If the FS has been found to have unreliable inodes, note
             that in path_flags. */
          if (!fs.hasgood_inode ())
            path_flags |= PATH_IHASH;
@@ -2721,7 +2723,8 @@ bool
 symlink_info::set_error (int in_errno)
 {
   bool res;
-  if (!(pflags & PATH_NO_ACCESS_CHECK) || in_errno == ENAMETOOLONG || in_errno 
== EIO)
+  if (!(pc_flags & PC_NO_ACCESS_CHECK)
+       || in_errno == ENAMETOOLONG || in_errno == EIO)
     {
       error = in_errno;
       res = true;
@@ -3103,7 +3106,7 @@ restart:
                 The handle has been opened with the FILE_OPEN_REPARSE_POINT
                 flag, so it's a handle to the reparse point, not a handle
                 to the volumes root dir. */
-             pflags &= ~PC_KEEP_HANDLE;
+             pc_flags &= ~PC_KEEP_HANDLE;
              /* Volume mount point:  The filesystem information for the top
                 level directory should be for the volume top level directory,
                 rather than for the reparse point itself.  So we fetch the
@@ -3202,7 +3205,7 @@ restart:
 
   if (h)
     {
-      if (pflags & PC_KEEP_HANDLE)
+      if (pc_flags & PC_KEEP_HANDLE)
        conv_hdl.set (h);
       else
        NtClose (h);
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 9812699..297eaa6 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -39,6 +39,8 @@ struct suffix_info
 
 extern suffix_info stat_suffixes[];
 
+/* DO NOT copy any of these files into the same set of flags as the
+   below path_types.  Ever. */
 enum pathconv_arg
 {
   PC_SYM_FOLLOW                = 0x0001,
@@ -76,7 +78,6 @@ enum path_types
   PATH_DOS             = MOUNT_DOS,
   PATH_IHASH           = MOUNT_IHASH,
   PATH_ALL_EXEC                = (PATH_CYGWIN_EXEC | PATH_EXEC),
-  PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
   PATH_CTTY            = 0x00400000,   /* could later be used as ctty */
   PATH_OPEN            = 0x00800000,   /* use open semantics */
                                        /* FIXME?  PATH_OPEN collides with

Reply via email to