Fixing GetFullPath (#16670)
authorAnirudh Agnihotry <anirudhagnihotry098@gmail.com>
Fri, 2 Mar 2018 05:53:25 +0000 (21:53 -0800)
committerGitHub <noreply@github.com>
Fri, 2 Mar 2018 05:53:25 +0000 (21:53 -0800)
src/mscorlib/shared/System/IO/Path.Windows.cs
src/mscorlib/shared/System/IO/Path.cs

index b921db9..0448337 100644 (file)
@@ -72,6 +72,9 @@ namespace System.IO
             if (IsPathFullyQualified(path))
                 return GetFullPath(path);
 
+            if (PathInternal.IsEffectivelyEmpty(path))
+                return basePath;
+
             int length = path.Length;
             string combinedPath = null;
 
@@ -80,7 +83,7 @@ namespace System.IO
                 // Path is current drive rooted i.e. starts with \:
                 // "\Foo" and "C:\Bar" => "C:\Foo"
                 // "\Foo" and "\\?\C:\Bar" => "\\?\C:\Foo"
-                combinedPath = Join(GetPathRoot(basePath.AsSpan()), path);
+                combinedPath = Join(GetPathRoot(basePath.AsSpan()), path.AsSpan().Slice(1)); // Cut the separator to ensure we don't end up with two separators when joining with the root.
             }
             else if (length >= 2 && PathInternal.IsValidDriveChar(path[0]) && path[1] == PathInternal.VolumeSeparatorChar)
             {
@@ -118,7 +121,8 @@ namespace System.IO
             // to GetFullPath() won't do anything by design. Additionally, GetFullPathName() in
             // Windows doesn't root them properly. As such we need to manually remove segments.
             return PathInternal.IsDevice(combinedPath)
-                ? RemoveRelativeSegments(combinedPath, PathInternal.GetRootLength(combinedPath))
+                // Paths at this point are in the form of \\?\C:\.\tmp we skip to the last character of the root when calling RemoveRelativeSegments to remove relative paths in such cases.
+                ? RemoveRelativeSegments(combinedPath, PathInternal.GetRootLength(combinedPath) - 1)
                 : GetFullPath(combinedPath);
         }
 
index 41ae1cd..fe6234c 100644 (file)
@@ -738,7 +738,7 @@ namespace System.IO
                         {
                             if (PathInternal.IsDirectorySeparator(sb[s]))
                             {
-                                sb.Length = s;
+                                sb.Length = (i + 3 >= path.Length && s <= skip ) ? s + 1 : s; // to avoid removing the complete "\tmp\" segment in cases like \\?\C:\tmp\..\, C:\tmp\..
                                 break;
                             }
                         }