diff options
author | Anirudh Agnihotry <anirudhagnihotry098@gmail.com> | 2018-03-12 16:47:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-12 16:47:47 -0700 |
commit | f5ae6d14d9d49dbb9f4e97f605d2a5cceab04879 (patch) | |
tree | 8ee275766a96b4208487513b8e079f6d23d2404c | |
parent | 3af716ef2cc8d9bcfd9d11998b908994f4d4ceda (diff) | |
download | coreclr-f5ae6d14d9d49dbb9f4e97f605d2a5cceab04879.tar.gz coreclr-f5ae6d14d9d49dbb9f4e97f605d2a5cceab04879.tar.bz2 coreclr-f5ae6d14d9d49dbb9f4e97f605d2a5cceab04879.zip |
Missing Case In Remove Relative Segments (#16869)
-rw-r--r-- | src/mscorlib/shared/System/IO/Path.Unix.cs | 2 | ||||
-rw-r--r-- | src/mscorlib/shared/System/IO/Path.Windows.cs | 10 | ||||
-rw-r--r-- | src/mscorlib/shared/System/IO/PathInternal.cs | 15 |
3 files changed, 17 insertions, 10 deletions
diff --git a/src/mscorlib/shared/System/IO/Path.Unix.cs b/src/mscorlib/shared/System/IO/Path.Unix.cs index 10d295fece..f364b84df0 100644 --- a/src/mscorlib/shared/System/IO/Path.Unix.cs +++ b/src/mscorlib/shared/System/IO/Path.Unix.cs @@ -34,7 +34,7 @@ namespace System.IO // We would ideally use realpath to do this, but it resolves symlinks, requires that the file actually exist, // and turns it into a full path, which we only want if fullCheck is true. - string collapsedString = PathInternal.RemoveRelativeSegments(path); + string collapsedString = PathInternal.RemoveRelativeSegments(path, PathInternal.GetRootLength(path)); Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path, "Either we've removed characters, or the string should be unmodified from the input path."); diff --git a/src/mscorlib/shared/System/IO/Path.Windows.cs b/src/mscorlib/shared/System/IO/Path.Windows.cs index 945bba3f4e..1934e8d502 100644 --- a/src/mscorlib/shared/System/IO/Path.Windows.cs +++ b/src/mscorlib/shared/System/IO/Path.Windows.cs @@ -117,12 +117,12 @@ namespace System.IO combinedPath = JoinInternal(basePath, path); } - // Device paths are normalized by definition, so passing something of this format - // 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. + // Device paths are normalized by definition, so passing something of this format (i.e. \\?\C:\.\tmp, \\.\C:\foo) + // to Windows APIs won't do anything by design. Additionally, GetFullPathName() in Windows doesn't root + // them properly. As such we need to manually remove segments and not use GetFullPath(). + return PathInternal.IsDevice(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. - ? PathInternal.RemoveRelativeSegments(combinedPath, PathInternal.GetRootLength(combinedPath) - 1) + ? PathInternal.RemoveRelativeSegments(combinedPath, PathInternal.GetRootLength(combinedPath)) : GetFullPath(combinedPath); } diff --git a/src/mscorlib/shared/System/IO/PathInternal.cs b/src/mscorlib/shared/System/IO/PathInternal.cs index 059f0cf0b9..c5cce00b8f 100644 --- a/src/mscorlib/shared/System/IO/PathInternal.cs +++ b/src/mscorlib/shared/System/IO/PathInternal.cs @@ -113,12 +113,19 @@ namespace System.IO /// <summary> /// Try to remove relative segments from the given path (without combining with a root). /// </summary> - /// <param name="skip">Skip the specified number of characters before evaluating.</param> - internal static string RemoveRelativeSegments(string path, int skip = 0) + /// <param name="rootLength">The length of the root of the given path</param> + internal static string RemoveRelativeSegments(string path, int rootLength) { - Debug.Assert(skip >= 0); + Debug.Assert(rootLength > 0); bool flippedSeparator = false; + int skip = rootLength; + // We treat "\.." , "\." and "\\" as a relative segment. We want to collapse the first separator past the root presuming + // the root actually ends in a separator. Otherwise the first segment for RemoveRelativeSegments + // in cases like "\\?\C:\.\" and "\\?\C:\..\", the first segment after the root will be ".\" and "..\" which is not considered as a relative segment and hence not be removed. + if (path[skip - 1] == '\\') + skip--; + Span<char> initialBuffer = stackalloc char[260 /* PathInternal.MaxShortPath */]; ValueStringBuilder sb = new ValueStringBuilder(initialBuffer); @@ -195,7 +202,7 @@ namespace System.IO return path; } - return sb.ToString(); + return sb.Length < rootLength ? path.Substring(0, rootLength) : sb.ToString(); } } } |