diff --git a/src/libraries/Common/src/Interop/Windows/mincore/Interop.CreateDirectory.cs b/src/libraries/Common/src/Interop/Windows/mincore/Interop.CreateDirectory.cs
index 3b603dadd8b13..1432d339f51a0 100644
--- a/src/libraries/Common/src/Interop/Windows/mincore/Interop.CreateDirectory.cs
+++ b/src/libraries/Common/src/Interop/Windows/mincore/Interop.CreateDirectory.cs
@@ -14,7 +14,8 @@ internal partial class mincore
internal static bool CreateDirectory(string path, ref SECURITY_ATTRIBUTES lpSecurityAttributes)
{
- path = PathInternal.AddExtendedPathPrefixForLongPaths(path);
+ // We always want to add for CreateDirectory to get around the legacy 248 character limitation
+ path = PathInternal.AddExtendedPathPrefix(path);
return CreateDirectoryPrivate(path, ref lpSecurityAttributes);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetFullPathNameW.cs b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetFullPathNameW.cs
index 2435e69694d7d..a78d9ce5f2b0a 100644
--- a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetFullPathNameW.cs
+++ b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetFullPathNameW.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -9,10 +10,30 @@ partial class Interop
{
partial class mincore
{
+ ///
+ /// WARNING: This overload does not implicitly handle long paths.
+ ///
[DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
internal unsafe static extern int GetFullPathNameW(char* path, int numBufferChars, char* buffer, IntPtr mustBeZero);
- [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
- internal static extern int GetFullPathNameW(string path, int numBufferChars, [Out]StringBuilder buffer, IntPtr mustBeZero);
+ [DllImport(Libraries.CoreFile_L1, EntryPoint = "GetFullPathNameW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ private static extern int GetFullPathNameWPrivate(string path, int numBufferChars, [Out]StringBuilder buffer, IntPtr mustBeZero);
+
+ internal static int GetFullPathNameW(string path, int numBufferChars, [Out]StringBuilder buffer, IntPtr mustBeZero)
+ {
+ bool wasExtended = PathInternal.IsExtended(path);
+ if (!wasExtended)
+ {
+ path = PathInternal.AddExtendedPathPrefixForLongPaths(path);
+ }
+ int result = GetFullPathNameWPrivate(path, buffer.Capacity, buffer, mustBeZero);
+
+ if (!wasExtended)
+ {
+ // We don't want to give back \\?\ if we possibly added it ourselves
+ PathInternal.RemoveExtendedPathPrefix(buffer);
+ }
+ return result;
+ }
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetLongPathNameW.cs b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetLongPathNameW.cs
index 41078977242ac..a28c275e5b553 100644
--- a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetLongPathNameW.cs
+++ b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetLongPathNameW.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.IO;
using System.Text;
using System.Runtime.InteropServices;
@@ -8,10 +9,30 @@ partial class Interop
{
partial class mincore
{
+ ///
+ /// WARNING: This overload does not implicitly handle long paths.
+ ///
[DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
internal unsafe static extern int GetLongPathNameW(char* path, char* longPathBuffer, int bufferLength);
- [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
- internal static extern int GetLongPathNameW(string path, [Out]StringBuilder longPathBuffer, int bufferLength);
+ [DllImport(Libraries.CoreFile_L1, EntryPoint = "GetLongPathNameW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ private static extern int GetLongPathNameWPrivate(string path, [Out]StringBuilder longPathBuffer, int bufferLength);
+
+ internal static int GetLongPathNameW(string path, [Out]StringBuilder longPathBuffer, int bufferLength)
+ {
+ bool wasExtended = PathInternal.IsExtended(path);
+ if (!wasExtended)
+ {
+ path = PathInternal.AddExtendedPathPrefixForLongPaths(path);
+ }
+ int result = GetLongPathNameWPrivate(path, longPathBuffer, longPathBuffer.Capacity);
+
+ if (!wasExtended)
+ {
+ // We don't want to give back \\?\ if we possibly added it ourselves
+ PathInternal.RemoveExtendedPathPrefix(longPathBuffer);
+ }
+ return result;
+ }
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetTempPathW.cs b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetTempPathW.cs
index ec2b41794324d..4f80fc7ce328b 100644
--- a/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetTempPathW.cs
+++ b/src/libraries/Common/src/Interop/Windows/mincore/Interop.GetTempPathW.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.IO;
using System.Text;
using System.Runtime.InteropServices;
diff --git a/src/libraries/Common/src/System/IO/PathInternal.Windows.cs b/src/libraries/Common/src/System/IO/PathInternal.Windows.cs
index f30d5c3ca3166..a8402e178c9c4 100644
--- a/src/libraries/Common/src/System/IO/PathInternal.Windows.cs
+++ b/src/libraries/Common/src/System/IO/PathInternal.Windows.cs
@@ -16,7 +16,7 @@ internal static partial class PathInternal
internal const string DevicePathPrefix = @"\\.\";
internal const int MaxShortPath = 260;
internal const int MaxShortDirectoryPath = 248;
- internal const int MaxExtendedPath = short.MaxValue;
+ internal const int MaxLongPath = short.MaxValue;
internal static readonly char[] InvalidPathChars =
{
@@ -41,16 +41,29 @@ internal static partial class PathInternal
///
internal static bool IsPathTooLong(string fullPath)
{
+ // We'll never know precisely what will fail as paths get changed internally in Windows and
+ // may grow to exceed MaxExtendedPath. We'll only try to catch ones we know will absolutely
+ // fail.
+
+ if (fullPath.Length < MaxLongPath - UncExtendedPathPrefix.Length)
+ {
+ // We won't push it over MaxLongPath
+ return false;
+ }
+
+ // We need to check if we have a prefix to account for one being implicitly added.
if (IsExtended(fullPath))
{
- return fullPath.Length >= MaxExtendedPath;
+ // We won't prepend, just check
+ return fullPath.Length >= MaxLongPath;
}
- else
+
+ if (fullPath.StartsWith(UncPathPrefix, StringComparison.Ordinal))
{
- // Will need to be updated with #2581 to allow all paths to MaxExtendedPath
- // minus legth of extended local or UNC prefix.
- return fullPath.Length >= MaxShortPath;
+ return fullPath.Length + UncExtendedPrefixToInsert.Length >= MaxLongPath;
}
+
+ return fullPath.Length + ExtendedPathPrefix.Length >= MaxLongPath;
}
///
@@ -58,16 +71,7 @@ internal static bool IsPathTooLong(string fullPath)
///
internal static bool IsDirectoryTooLong(string fullPath)
{
- if (IsExtended(fullPath))
- {
- return fullPath.Length >= MaxExtendedPath;
- }
- else
- {
- // Will need to be updated with #2581 to allow all paths to MaxExtendedPath
- // minus legth of extended local or UNC prefix.
- return fullPath.Length >= MaxShortDirectoryPath;
- }
+ return IsPathTooLong(fullPath);
}
///
@@ -272,17 +276,17 @@ internal static bool IsPathRelative(string path)
return true;
}
- if ((path[0] == '\\') || (path[0] == '/'))
+ if (IsDirectorySeparator(path[0]))
{
// There is no valid way to specify a relative path with two initial slashes
- return !((path[1] == '\\') || (path[1] == '/'));
+ return !(IsDirectorySeparator(path[1]));
}
// The only way to specify a fixed path that doesn't begin with two slashes
// is the drive, colon, slash format- i.e. C:\
return !((path.Length >= 3)
- && (path[1] == ':')
- && ((path[2] == '\\') || (path[2] == '/')));
+ && (path[1] == Path.VolumeSeparatorChar)
+ && (IsDirectorySeparator(path[2])));
}
internal static bool IsDirectorySeparator(char c)
diff --git a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs
index c0a7d15571cf9..664774729283b 100644
--- a/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs
+++ b/src/libraries/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs
@@ -29,6 +29,8 @@ public void AddExtendedPathPrefixTest(string path, string expected)
InlineData(@"\\?", false),
InlineData(@"\\", false),
InlineData(@"//", false),
+ InlineData(@"\a", true),
+ InlineData(@"/a", true),
InlineData(@"\", true),
InlineData(@"/", true),
InlineData(@"C:Path", true),
@@ -36,6 +38,7 @@ public void AddExtendedPathPrefixTest(string path, string expected)
InlineData(@"\\?\C:\Path", false),
InlineData(@"Path", true),
InlineData(@"X", true)]
+ [PlatformSpecific(PlatformID.Windows)]
public void IsPathRelative(string path, bool expected)
{
Assert.Equal(expected, PathInternal.IsPathRelative(path));
diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs b/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs
index c7d6eb6df2e5d..421ee187e0319 100644
--- a/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs
+++ b/src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory.cs
@@ -210,20 +210,44 @@ public void DirectoryWithComponentLongerThanMaxComponentAsPath_ThrowsPathTooLong
[Fact]
[PlatformSpecific(PlatformID.Windows)]
- public void DirectoryLongerThanMaxPathAsPath_ThrowsPathTooLongException()
+ public void DirectoryLongerThanMaxPath_Succeeds()
{
var paths = IOInputs.GetPathsLongerThanMaxPath();
Assert.All(paths, (path) =>
+ {
+ DirectoryInfo result = Create(path);
+ Assert.True(Directory.Exists(result.FullName));
+ });
+ }
+
+ [Fact]
+ [PlatformSpecific(PlatformID.Windows)]
+ public void DirectoryLongerThanMaxLongPath_ThrowsPathTooLongException()
+ {
+ var paths = IOInputs.GetPathsLongerThanMaxLongPath();
+ Assert.All(paths, (path) =>
+ {
+ Assert.Throws(() => Create(path));
+ });
+ }
+
+ [Fact]
+ [PlatformSpecific(PlatformID.Windows)]
+ public void DirectoryLongerThanMaxLongPathWithExtendedSyntax_ThrowsPathTooLongException()
+ {
+ var paths = IOInputs.GetPathsLongerThanMaxLongPath(useExtendedSyntax: true);
+ Assert.All(paths, (path) =>
{
Assert.Throws(() => Create(path));
});
}
+
[Fact]
[PlatformSpecific(PlatformID.Windows)]
- public void ExtendedDirectoryLongerThanLegacyMaxPathSucceeds()
+ public void ExtendedDirectoryLongerThanLegacyMaxPath_Succeeds()
{
- var paths = IOInputs.GetPathsLongerThanMaxPath(useExtendedSyntax: true, includeExtendedMaxPath: false);
+ var paths = IOInputs.GetPathsLongerThanMaxPath(useExtendedSyntax: true);
Assert.All(paths, (path) =>
{
Assert.True(Create(path).Exists);
@@ -232,12 +256,13 @@ public void ExtendedDirectoryLongerThanLegacyMaxPathSucceeds()
[Fact]
[PlatformSpecific(PlatformID.Windows)]
- public void DirectoryLongerThanMaxDirectoryAsPath_ThrowsPathTooLongException()
+ public void DirectoryLongerThanMaxDirectoryAsPath_Succeeds()
{
var paths = IOInputs.GetPathsLongerThanMaxDirectory();
Assert.All(paths, (path) =>
{
- Assert.Throws(() => Create(path));
+ var result = Create(path);
+ Assert.True(Directory.Exists(result.FullName));
});
}
diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs
index f01bd4a89c0a3..42e03c760c803 100644
--- a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs
+++ b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs
@@ -105,9 +105,9 @@ public void DotDotAsPath_ReturnsTrue()
}
[Fact]
- public void DirectoryLongerThanMaxPathAsPath_DoesntThrow()
+ public void DirectoryLongerThanMaxLongPath_DoesntThrow()
{
- Assert.All((IOInputs.GetPathsLongerThanMaxPath()), (path) =>
+ Assert.All((IOInputs.GetPathsLongerThanMaxLongPath()), (path) =>
{
Assert.False(Exists(path), path);
});
diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs
index f2b010b9652de..9914d14ec435f 100644
--- a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs
+++ b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs
@@ -127,11 +127,11 @@ public void IncludeSubdirectories()
}
[Fact]
- public void Path_Longer_Than_MaxPath_Throws_Exception()
+ public void Path_Longer_Than_MaxLongPath_Throws_Exception()
{
string testDir = GetTestFilePath();
Directory.CreateDirectory(testDir);
- Assert.All((IOInputs.GetPathsLongerThanMaxPath()), (path) =>
+ Assert.All((IOInputs.GetPathsLongerThanMaxLongPath()), (path) =>
{
Assert.Throws(() => Move(testDir, path));
Assert.Throws(() => Move(path, testDir));
@@ -144,14 +144,26 @@ public void Path_Longer_Than_MaxPath_Throws_Exception()
[Fact]
[PlatformSpecific(PlatformID.Windows)]
- public void Path_With_Longer_Than_MaxDirectory_Throws_Exception()
+ public void Path_With_Longer_Than_MaxDirectory_Succeeds()
{
string testDir = GetTestFilePath();
Directory.CreateDirectory(testDir);
+ Assert.True(Directory.Exists(testDir), "test directory should exist");
Assert.All((IOInputs.GetPathsLongerThanMaxDirectory()), (path) =>
{
- Assert.Throws(() => Move(testDir, path));
- Assert.Throws(() => Move(path, testDir));
+ string baseDestinationPath = Path.GetDirectoryName(path);
+ if (!Directory.Exists(baseDestinationPath))
+ {
+ Directory.CreateDirectory(baseDestinationPath);
+ }
+ Assert.True(Directory.Exists(baseDestinationPath), "base destination path should exist");
+
+ Move(testDir, path);
+ Assert.False(Directory.Exists(testDir), "source directory should exist");
+ Assert.True(Directory.Exists(path), "destination directory should exist");
+ Move(path, testDir);
+ Assert.False(Directory.Exists(path), "source directory should exist");
+ Assert.True(Directory.Exists(testDir), "destination directory should exist");
});
}
diff --git a/src/libraries/System.IO.FileSystem/tests/File/Move.cs b/src/libraries/System.IO.FileSystem/tests/File/Move.cs
index ca4d72650d002..a4038a2f49ed8 100644
--- a/src/libraries/System.IO.FileSystem/tests/File/Move.cs
+++ b/src/libraries/System.IO.FileSystem/tests/File/Move.cs
@@ -144,13 +144,43 @@ public void FileNameWithSignificantWhitespace()
}
[Fact]
+ [PlatformSpecific(PlatformID.Windows)]
+ public void MaxPath_Windows()
+ {
+ // Create a destination path longer than the traditional Windows limit of 256 characters,
+ // but under the long path limitation (32K).
+
+ string testFileSource = Path.Combine(TestDirectory, GetTestFileName());
+ File.Create(testFileSource).Dispose();
+ Assert.True(File.Exists(testFileSource), "test file should exist");
+
+ Assert.All(IOInputs.GetPathsLongerThanMaxPath(), (path) =>
+ {
+ string baseDestinationPath = Path.GetDirectoryName(path);
+ if (!Directory.Exists(baseDestinationPath))
+ {
+ Directory.CreateDirectory(baseDestinationPath);
+ }
+ Assert.True(Directory.Exists(baseDestinationPath), "base destination path should exist");
+
+ Move(testFileSource, path);
+ Assert.True(File.Exists(path), "moved test file should exist");
+ File.Delete(testFileSource);
+ Assert.False(File.Exists(testFileSource), "source test file should not exist");
+ Move(path, testFileSource);
+ Assert.True(File.Exists(testFileSource), "restored test file should exist");
+ });
+ }
+
+ [Fact]
+ [PlatformSpecific(PlatformID.AnyUnix)]
public void LongPath()
{
//Create a destination path longer than the traditional Windows limit of 256 characters
string testFileSource = Path.Combine(TestDirectory, GetTestFileName());
File.Create(testFileSource).Dispose();
- Assert.All(IOInputs.GetPathsLongerThanMaxPath(), (path) =>
+ Assert.All(IOInputs.GetPathsLongerThanMaxLongPath(), (path) =>
{
Assert.Throws(() => Move(testFileSource, path));
File.Delete(testFileSource);
diff --git a/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs b/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs
index 0591a514dbf0c..4cc08ea854d7f 100644
--- a/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs
+++ b/src/libraries/System.IO.FileSystem/tests/PortedCommon/IOInputs.cs
@@ -21,13 +21,18 @@ internal static class IOInputs
// Max path length (minus trailing \0). Unix values vary system to system; just using really long values here likely to be more than on the average system.
public static readonly int MaxPath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 259 : 10000;
+ // Same as MaxPath on Unix
+ public static readonly int MaxLongPath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? MaxExtendedPath : MaxPath;
+
// Windows specific, this is the maximum length that can be passed to APIs taking directory names, such as Directory.CreateDirectory & Directory.Move.
// Does not include the trailing \0.
+ // We now do the appropriate wrapping to allow creating longer directories. Like MaxPath, this is a legacy restriction.
public static readonly int MaxDirectory = 247;
// Windows specific, this is the maximum length that can be passed using extended syntax. Does not include the trailing \0.
public static readonly int MaxExtendedPath = short.MaxValue - 1;
+
public const int MaxComponent = 255;
public const string ExtendedPrefix = @"\\?\";
@@ -218,16 +223,17 @@ public static IEnumerable GetPathsLongerThanMaxDirectory()
yield return GetLongPath(MaxDirectory + 3);
}
- public static IEnumerable GetPathsLongerThanMaxPath(bool useExtendedSyntax = false, bool includeExtendedMaxPath = true)
+ public static IEnumerable GetPathsLongerThanMaxPath(bool useExtendedSyntax = false)
{
yield return GetLongPath(MaxPath + 1, useExtendedSyntax);
yield return GetLongPath(MaxPath + 2, useExtendedSyntax);
yield return GetLongPath(MaxPath + 3, useExtendedSyntax);
- if (includeExtendedMaxPath)
- {
- yield return GetLongPath(MaxExtendedPath + 1, useExtendedSyntax);
- yield return GetLongPath(MaxExtendedPath + 2, useExtendedSyntax);
- }
+ }
+
+ public static IEnumerable GetPathsLongerThanMaxLongPath(bool useExtendedSyntax = false)
+ {
+ yield return GetLongPath(MaxExtendedPath + 1 - (useExtendedSyntax ? 0 : ExtendedPrefix.Length), useExtendedSyntax);
+ yield return GetLongPath(MaxExtendedPath + 2 - (useExtendedSyntax ? 0 : ExtendedPrefix.Length), useExtendedSyntax);
}
private static string GetLongPath(int characterCount, bool extended = false)
diff --git a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Unix.cs b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Unix.cs
index e3e25fbc77ca4..1e7cc016a727b 100644
--- a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Unix.cs
+++ b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Unix.cs
@@ -18,6 +18,7 @@ public static partial class Path
private static readonly char[] InvalidFileNameChars = { '\0', '/' };
private static readonly int MaxPath = Interop.libc.MaxPath;
+ private static readonly int MaxLongPath = MaxPath;
private static readonly int MaxComponentLength = Interop.libc.MaxName;
private static bool IsDirectoryOrVolumeSeparator(char c)
diff --git a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Windows.cs b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Windows.cs
index a65e1b7eb545d..3ab932d0d3223 100644
--- a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Windows.cs
+++ b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.Windows.cs
@@ -33,7 +33,7 @@ public static partial class Path
// For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
internal static readonly int MaxPath = 260;
private static readonly int MaxComponentLength = 255;
- private const int MaxLongPath = 32000;
+ internal static readonly int MaxLongPath = short.MaxValue;
private static bool IsDirectoryOrVolumeSeparator(char c)
{
@@ -323,8 +323,10 @@ private unsafe static string NormalizePath(string path, bool fullCheck, int maxP
}
int thisPos = newBuffer.Length - 1;
- if (thisPos - lastDirectorySeparatorPos > MaxComponentLength)
+ if (thisPos - lastDirectorySeparatorPos > MaxComponentLength + 1)
{
+ // Components can be up to 255 characters plus an additional null,
+ // so separators can be 256 characters apart
throw new PathTooLongException(SR.IO_PathTooLong);
}
lastDirectorySeparatorPos = thisPos;
@@ -405,7 +407,8 @@ private unsafe static string NormalizePath(string path, bool fullCheck, int maxP
index++;
} // end while
- if (newBuffer.Length - 1 - lastDirectorySeparatorPos > MaxComponentLength)
+ // Components can be up to 255 characters plus an additional null
+ if (newBuffer.Length - lastDirectorySeparatorPos > MaxComponentLength)
{
throw new PathTooLongException(SR.IO_PathTooLong);
}
diff --git a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.cs b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.cs
index 7779628931b8c..73628bf2e231e 100644
--- a/src/libraries/System.Runtime.Extensions/src/System/IO/Path.cs
+++ b/src/libraries/System.Runtime.Extensions/src/System/IO/Path.cs
@@ -134,21 +134,15 @@ private static string GetFullPathInternal(string path)
[System.Security.SecuritySafeCritical] // auto-generated
private static string NormalizePath(string path, bool fullCheck)
{
- return NormalizePath(path, fullCheck, MaxPath);
+ return NormalizePath(path, fullCheck, MaxLongPath, expandShortPaths: true);
}
[System.Security.SecuritySafeCritical] // auto-generated
private static string NormalizePath(string path, bool fullCheck, bool expandShortPaths)
{
- return NormalizePath(path, fullCheck, MaxPath, expandShortPaths);
+ return NormalizePath(path, fullCheck, MaxLongPath, expandShortPaths);
}
-
- [System.Security.SecuritySafeCritical] // auto-generated
- private static string NormalizePath(string path, bool fullCheck, int maxPathLength)
- {
- return NormalizePath(path, fullCheck, maxPathLength, expandShortPaths: true);
- }
-
+
// Returns the name and extension parts of the given path. The resulting
// string contains the characters of path that follow the last
// separator in path. The resulting string is null if path is null.
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
index 0172718f283ba..ec314f4b4cf02 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
@@ -408,7 +408,9 @@ public static void GetFullPath_Windows_NormalizedLongPathTooLong()
{
longPath.Append(Path.DirectorySeparatorChar).Append('a').Append(Path.DirectorySeparatorChar).Append('.');
}
- Assert.Throws(() => Path.GetFullPath(longPath.ToString()));
+
+ // Now no longer throws unless over ~32K
+ Assert.NotNull(Path.GetFullPath(longPath.ToString()));
}
[PlatformSpecific(PlatformID.Windows)]
@@ -453,11 +455,19 @@ public static void GetFullPath_Windows_ArgumentExceptionPaths(string path)
Assert.Throws(() => Path.GetFullPath(path));
}
+ [PlatformSpecific(PlatformID.Windows)]
+ [Fact]
+ public static void GetFullPath_Windows_MaxPathNotTooLong()
+ {
+ // Shouldn't throw anymore
+ Path.GetFullPath(@"C:\" + new string('a', 255) + @"\");
+ }
+
[PlatformSpecific(PlatformID.Windows)]
[Fact]
public static void GetFullPath_Windows_PathTooLong()
{
- Assert.Throws(() => Path.GetFullPath(@"C:\" + new string('a', 255) + @"\"));
+ Assert.Throws(() => Path.GetFullPath(@"C:\" + new string('a', short.MaxValue) + @"\"));
}
[PlatformSpecific(PlatformID.Windows)]