[PATCH] Cygwin: normalize_win32_path: improve error checking

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Cygwin: normalize_win32_path: improve error checking

Ken Brown-6
If the src path starts with the Win32 long path prefix \\?\ or the NT
object directory prefix \??\, require the prefix to be followed by
UNC\ or <drive letter>:\.  Otherwise return EINVAL.

This fixes the assertion failure in symlink_info::check that was
reported here:

  https://cygwin.com/ml/cygwin/2019-09/msg00228.html

That assertion failure was caused by normalize_win32_path returning a
path with no backslashes when the input src path was '\\?\DRIVE'.
---
 winsup/cygwin/path.cc | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 2fbacd881..2eeb4fd1c 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1406,15 +1406,18 @@ normalize_win32_path (const char *src, char *dst, char *&tail)
   bool beg_src_slash = isdirsep (src[0]);
 
   tail = dst;
-  /* Skip long path name prefixes in Win32 or NT syntax. */
+  /* Skip Win32 long path name prefix and NT object directory prefix. */
   if (beg_src_slash && (src[1] == '?' || isdirsep (src[1]))
       && src[2] == '?' && isdirsep (src[3]))
     {
       src += 4;
-      if (src[1] != ':') /* native UNC path */
+      if (src[1] == ':' && isdirsep (src[2]))
+ beg_src_slash = false;
+      else if (!strncmp (src, "UNC", 3) && isdirsep (src[3]))
+ /* native UNC path */
  src += 2; /* Fortunately the first char is not copied... */
       else
- beg_src_slash = false;
+ return EINVAL;
     }
   if (beg_src_slash && isdirsep (src[1]))
     {
--
2.21.0