From 9da32114e4779619b3cbbb4e3d795a5247e964d9 Mon Sep 17 00:00:00 2001
From: Ron Yorston <rmy@pobox.com>
Date: Fri, 8 Mar 2019 17:27:27 +0000
Subject: win32: extend normalisation of paths in realpath(3)

The code to normalise paths in resolve_symlinks(), which is used
by realpath(3), was incomplete and unable to handle UNC paths.
Make an ASCII version of normalize_ntpath() to extend the cases
covered.

This fixes a regression introduced by commit 585d17d26 (win32:
canonicalize path in chdir(2)):  it wasn't possible to change
to a directory with a UNC path.
---
 win32/mingw.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/win32/mingw.c b/win32/mingw.c
index b1a8b9711..44356d6b0 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1001,6 +1001,25 @@ int link(const char *oldpath, const char *newpath)
 	return 0;
 }
 
+static char *normalize_ntpathA(char *buf)
+{
+	/* fix absolute path prefixes */
+	if (buf[0] == '\\') {
+		/* strip NT namespace prefixes */
+		if (!strncmp(buf, "\\??\\", 4) ||
+		    !strncmp(buf, "\\\\?\\", 4))
+			buf += 4;
+		else if (!strncasecmp(buf, "\\DosDevices\\", 12))
+			buf += 12;
+		/* replace remaining '...UNC\' with '\\' */
+		if (!strncasecmp(buf, "UNC\\", 4)) {
+			buf += 2;
+			*buf = '\\';
+		}
+	}
+	return buf;
+}
+
 static char *resolve_symlinks(char *path)
 {
 	HANDLE h;
@@ -1022,8 +1041,7 @@ static char *resolve_symlinks(char *path)
 		status = GetFinalPathNameByHandleA(h, path, MAX_PATH,
 							FILE_NAME_NORMALIZED|VOLUME_NAME_DOS);
 		if (status != 0 && status < MAX_PATH) {
-			/* skip '\\?\' prefix */
-			ptr = (!strncmp(path, "\\\\?\\", 4)) ? (path + 4) : path;
+			ptr = normalize_ntpathA(path);
 			goto end;
 		}
 	}
-- 
cgit v1.2.3-55-g6feb