Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit dc13131

Browse files
JeremyKuhnejkotas
authored andcommitted
Fix path issues (#16554)
Path tests weren't running so a few issues sneaked in.
1 parent c2481cd commit dc13131

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

src/mscorlib/shared/System/IO/Path.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public static string ChangeExtension(string path, string extension)
7979
/// </remarks>
8080
public static string GetDirectoryName(string path)
8181
{
82-
if (PathInternal.IsEffectivelyEmpty(path))
82+
if (path == null || PathInternal.IsEffectivelyEmpty(path))
8383
return null;
8484

8585
int end = GetDirectoryNameOffset(path);

src/mscorlib/shared/System/IO/PathHelper.Windows.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ private static string TryExpandShortFileName(ref ValueStringBuilder outputBuilde
203203
}
204204
}
205205

206+
// Need to trim out the trailing separator in the input builder
207+
inputBuilder.Length = inputBuilder.Length - 1;
208+
206209
// If we were able to expand the path, use it, otherwise use the original full path result
207210
ref ValueStringBuilder builderToUse = ref (success ? ref outputBuilder : ref inputBuilder);
208211

src/mscorlib/shared/System/IO/PathInternal.Windows.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ internal static bool IsDevice(ReadOnlySpan<char> path)
129129
);
130130
}
131131

132+
/// <summary>
133+
/// Returns true if the path is a device UNC (\\?\UNC\, \\.\UNC\)
134+
/// </summary>
135+
internal static bool IsDeviceUNC(ReadOnlySpan<char> path)
136+
{
137+
return path.Length >= UncExtendedPrefixLength
138+
&& IsDevice(path)
139+
&& IsDirectorySeparator(path[7])
140+
&& path[4] == 'U'
141+
&& path[5] == 'N'
142+
&& path[6] == 'C';
143+
}
144+
132145
/// <summary>
133146
/// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the
134147
/// path matches exactly (cannot use alternate directory separators) Windows will skip normalization
@@ -178,12 +191,12 @@ internal static int GetRootLength(ReadOnlySpan<char> path)
178191
int volumeSeparatorLength = 2; // Length to the colon "C:"
179192
int uncRootLength = 2; // Length to the start of the server name "\\"
180193

181-
bool extendedSyntax = StartsWithOrdinal(path, ExtendedPathPrefix);
182-
bool extendedUncSyntax = StartsWithOrdinal(path, UncExtendedPathPrefix);
183-
if (extendedSyntax)
194+
bool deviceSyntax = IsDevice(path);
195+
bool deviceUnc = deviceSyntax && IsDeviceUNC(path);
196+
if (deviceSyntax)
184197
{
185198
// Shift the position we look for the root from to account for the extended prefix
186-
if (extendedUncSyntax)
199+
if (deviceUnc)
187200
{
188201
// "\\" -> "\\?\UNC\"
189202
uncRootLength = UncExtendedPathPrefix.Length;
@@ -195,12 +208,12 @@ internal static int GetRootLength(ReadOnlySpan<char> path)
195208
}
196209
}
197210

198-
if ((!extendedSyntax || extendedUncSyntax) && pathLength > 0 && IsDirectorySeparator(path[0]))
211+
if ((!deviceSyntax || deviceUnc) && pathLength > 0 && IsDirectorySeparator(path[0]))
199212
{
200213
// UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo")
201214

202215
i = 1; // Drive rooted (\foo) is one character
203-
if (extendedUncSyntax || (pathLength > 1 && IsDirectorySeparator(path[1])))
216+
if (deviceUnc || (pathLength > 1 && IsDirectorySeparator(path[1])))
204217
{
205218
// UNC (\\?\UNC\ or \\), scan past the next two directory separators at most
206219
// (e.g. to \\?\UNC\Server\Share or \\Server\Share\)

0 commit comments

Comments
 (0)