Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 0 additions & 63 deletions src/Build.UnitTests/Evaluation/Expander_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -922,27 +922,6 @@ public void ItemIncludeContainsMultipleItemReferences()
logger.AssertLogContains("Item CleanFiles=foo.obj;bar.obj");
}

#if FEATURE_LEGACY_GETFULLPATH
/// <summary>
/// Bad path when getting metadata through ->Metadata function
/// </summary>
[LongPathSupportDisabledFact]
public void InvalidPathAndMetadataItemFunctionPathTooLong()
{
MockLogger logger = Helpers.BuildProjectWithNewOMExpectFailure(@"
<Project DefaultTargets='Build'>
<ItemGroup>
<x Include='" + new string('x', 250) + @"'/>
</ItemGroup>
<Target Name='Build'>
<Message Text=""@(x->Metadata('FullPath'))"" />
</Target>
</Project>", false);

logger.AssertLogContains("MSB4023");
}
#endif

/// <summary>
/// Bad path with illegal windows chars when getting metadata through ->Metadata function
/// </summary>
Expand Down Expand Up @@ -981,27 +960,6 @@ public void InvalidMetadataName()
logger.AssertLogContains("MSB4023");
}

#if FEATURE_LEGACY_GETFULLPATH
/// <summary>
/// Bad path when getting metadata through ->WithMetadataValue function
/// </summary>
[LongPathSupportDisabledFact]
public void InvalidPathAndMetadataItemFunctionPathTooLong2()
{
MockLogger logger = Helpers.BuildProjectWithNewOMExpectFailure(@"
<Project DefaultTargets='Build'>
<ItemGroup>
<x Include='" + new string('x', 250) + @"'/>
</ItemGroup>
<Target Name='Build'>
<Message Text=""@(x->WithMetadataValue('FullPath', 'x'))"" />
</Target>
</Project>", false);

logger.AssertLogContains("MSB4023");
}
#endif

/// <summary>
/// Bad path with illegal windows chars when getting metadata through ->WithMetadataValue function
/// </summary>
Expand Down Expand Up @@ -1040,27 +998,6 @@ public void InvalidMetadataName2()
logger.AssertLogContains("MSB4023");
}

#if FEATURE_LEGACY_GETFULLPATH
/// <summary>
/// Bad path when getting metadata through ->AnyHaveMetadataValue function
/// </summary>
[LongPathSupportDisabledFact]
public void InvalidPathAndMetadataItemFunctionPathTooLong3()
{
MockLogger logger = Helpers.BuildProjectWithNewOMExpectFailure(@"
<Project DefaultTargets='Build'>
<ItemGroup>
<x Include='" + new string('x', 250) + @"'/>
</ItemGroup>
<Target Name='Build'>
<Message Text=""@(x->AnyHaveMetadataValue('FullPath', 'x'))"" />
</Target>
</Project>", false);

logger.AssertLogContains("MSB4023");
}
#endif

/// <summary>
/// Bad path with illegal windows chars when getting metadata through ->AnyHaveMetadataValue function
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,7 @@ public void FallbackImportWithInvalidProjectValue(string projectValue)
}
else
{
#if NETFRAMEWORK
logger.AssertLogContains("MSB4102");
#endif
logger.AssertLogDoesntContain("MSB4102");
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/Directory.BeforeCommon.targets
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
<DefineConstants>$(DefineConstants);FEATURE_INSTALLED_MSBUILD</DefineConstants>
<!-- Directory.GetCurrentDirectory The pre .Net 4.6.2 implementation of Directory.GetCurrentDirectory is slow and creates strings in its work. -->
<DefineConstants>$(DefineConstants);FEATURE_LEGACY_GETCURRENTDIRECTORY</DefineConstants>
<!-- Path.GetFullPath The pre .Net 4.6.2 implementation of Path.GetFullPath is slow and creates strings in its work. -->
<DefineConstants>$(DefineConstants);FEATURE_LEGACY_GETFULLPATH</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_NAMED_PIPE_SECURITY_CONSTRUCTOR</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_PERFORMANCE_COUNTERS</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_PIPE_SECURITY</DefineConstants>
Expand Down
42 changes: 0 additions & 42 deletions src/Framework.UnitTests/FileUtilities_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,33 +462,6 @@ public void NormalizePathEmpty()
});
}

[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC1()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(@"\\"));
});
}

[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC2()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Null(FileUtilities.NormalizePath(@"\\XXX\"));
});
}

[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathBadUNC3()
{
Assert.Throws<ArgumentException>(() =>
{
Assert.Equal(@"\\localhost", FileUtilities.NormalizePath(@"\\localhost"));
});
}

[WindowsOnlyFact]
public void NormalizePathGoodUNC()
{
Expand All @@ -502,27 +475,12 @@ public void NormalizePathTooLongWithDots()
Assert.Equal(@"c:\abc\def", FileUtilities.NormalizePath(@"c:\abc\" + longPart + @"\..\def"));
}

[WindowsFullFrameworkOnlyFact(additionalMessage: ".NET Core 2.1+ no longer validates paths: https://github.com/dotnet/corefx/issues/27779#issuecomment-371253486.")]
public void NormalizePathInvalid()
{
string filePath = @"c:\aardvark\|||";

Assert.Throws<ArgumentException>(() =>
{
FileUtilities.NormalizePath(filePath);
});
}

[WindowsOnlyFact]
public void CannotNormalizePathWithNewLineAndSpace()
{
string filePath = "\r\n C:\\work\\sdk3\\artifacts\\tmp\\Debug\\SimpleNamesWi---6143883E\\NETFrameworkLibrary\\bin\\Debug\\net462\\NETFrameworkLibrary.dll\r\n ";

#if FEATURE_LEGACY_GETFULLPATH
Assert.Throws<ArgumentException>(() => FileUtilities.NormalizePath(filePath));
#else
Assert.NotEqual("C:\\work\\sdk3\\artifacts\\tmp\\Debug\\SimpleNamesWi---6143883E\\NETFrameworkLibrary\\bin\\Debug\\net462\\NETFrameworkLibrary.dll", FileUtilities.NormalizePath(filePath));
#endif
}

[Fact]
Expand Down
70 changes: 4 additions & 66 deletions src/Framework/FileUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ private static bool IsValidRelativePathBound(char? c)
internal static string NormalizePath(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
string fullPath = GetFullPath(path);
string fullPath = NewPath.GetFullPath(path);
return FixFilePath(fullPath);
}

Expand All @@ -680,68 +680,6 @@ internal static string NormalizePath(params string[] paths)
return NormalizePath(Path.Combine(paths));
}

private static string GetFullPath(string path)
{
#if FEATURE_LEGACY_GETFULLPATH
if (NativeMethods.IsWindows)
{
string uncheckedFullPath = NativeMethods.GetFullPath(path);

if (IsPathTooLong(uncheckedFullPath))
{
throw new PathTooLongException(SR.FormatPathTooLong(path, NativeMethods.MaxPath));
}

// We really don't care about extensions here, but Path.HasExtension provides a great way to
// invoke the CLR's invalid path checks (these are independent of path length)
Path.HasExtension(uncheckedFullPath);

// If we detect we are a UNC path then we need to use the regular get full path in order to do the correct checks for UNC formatting
// and security checks for strings like \\?\GlobalRoot
return IsUNCPath(uncheckedFullPath) ? Path.GetFullPath(uncheckedFullPath) : uncheckedFullPath;
}
#endif

return Path.GetFullPath(path);
}

#if FEATURE_LEGACY_GETFULLPATH
private static bool IsUNCPath(string path)
{
if (!NativeMethods.IsWindows || !path.StartsWith(@"\\", StringComparison.Ordinal))
{
return false;
}
bool isUNC = true;
for (int i = 2; i < path.Length - 1; i++)
{
if (path[i] == '\\')
{
isUNC = false;
break;
}
}

/*
From Path.cs in the CLR

Throw an ArgumentException for paths like \\, \\server, \\server\
This check can only be properly done after normalizing, so
\\foo\.. will be properly rejected. Also, reject \\?\GLOBALROOT\
(an internal kernel path) because it provides aliases for drives.

throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegalUNC"));

// Check for \\?\Globalroot, an internal mechanism to the kernel
// that provides aliases for drives and other undocumented stuff.
// The kernel team won't even describe the full set of what
// is available here - we don't want managed apps mucking
// with this for security reasons.
*/
return isUNC || path.IndexOf(@"\\?\globalroot", StringComparison.OrdinalIgnoreCase) != -1;
}
#endif // FEATURE_LEGACY_GETFULLPATH

/// <summary>
/// Normalizes all path separators (both forward and back slashes) to forward slashes.
/// This is platform-independent, unlike FrameworkFileUtilities.FixFilePath which only normalizes on non-Windows platforms.
Expand Down Expand Up @@ -1379,8 +1317,8 @@ internal static string MakeRelative(string basePath, string path)
ArgumentNullException.ThrowIfNull(basePath);
ArgumentException.ThrowIfNullOrEmpty(path);

string fullBase = GetFullPath(basePath);
string fullPath = GetFullPath(path);
string fullBase = NewPath.GetFullPath(basePath);
string fullPath = NewPath.GetFullPath(path);

string[] splitBase = fullBase.Split(MSBuildConstants.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
string[] splitPath = fullPath.Split(MSBuildConstants.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries);
Expand Down Expand Up @@ -1678,7 +1616,7 @@ internal static string GetDirectoryNameOfFileAbove(string startingDirectory, str
fileSystem ??= DefaultFileSystem;

// Canonicalize our starting location
string? lookInDirectory = GetFullPath(startingDirectory);
string? lookInDirectory = NewPath.GetFullPath(startingDirectory);

do
{
Expand Down
26 changes: 0 additions & 26 deletions src/Framework/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,32 +1217,6 @@ internal static bool SetCurrentDirectory(string path)
return true;
}

#if FEATURE_WINDOWSINTEROP
[SupportedOSPlatform("windows6.1")]
internal static unsafe string GetFullPath(string path)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JeremyKuhne since you both fixed this and did Microsoft.IO.Redist -- what do you think of this change?

{
using BufferScope<char> buffer = new(stackalloc char[(int)PInvoke.MAX_PATH]);
int fullPathLength = (int)PInvoke.GetFullPathName(path, buffer, out _);

// If user is using long paths we could need to allocate a larger buffer
if (fullPathLength > buffer.Length)
{
buffer.EnsureCapacity(fullPathLength);
fullPathLength = (int)PInvoke.GetFullPathName(path, buffer, out _);
}

if (fullPathLength == 0)
{
HRESULT.FromLastError().ThrowOnFailure();
}

// Avoid creating new strings unnecessarily
ReadOnlySpan<char> result = buffer.AsSpan().Slice(0, fullPathLength);
return result.SequenceEqual(path.AsSpan()) ? path : result.ToString();
}

#endif

internal static (bool acceptAnsiColorCodes, bool outputIsScreen, uint? originalConsoleMode) QueryIsScreenAndTryEnableAnsiColorCodes(bool useStandardError = false)
{
if (Console.IsOutputRedirected)
Expand Down
Loading
Loading