Skip to content

Commit

Permalink
[release/6.0] Fix detection of unsupported links (#58399)
Browse files Browse the repository at this point in the history
* Fix detection of unsupported links

* Add Directory.Exists check

* Fix CI issue caused by local testing code

Co-authored-by: David Cantu <[email protected]>
  • Loading branch information
github-actions[bot] and jozkee authored Sep 8, 2021
1 parent 596214e commit c7e5075
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.IO.Enumeration;
using System.Linq;
using Xunit;

namespace System.IO.Tests
Expand Down Expand Up @@ -482,6 +484,34 @@ protected void CreateSymbolicLink_PathToTarget_RelativeToLinkPath_Internal(bool
Assert.Equal(Path.GetDirectoryName(linkInfo.FullName), Path.GetDirectoryName(targetInfo.FullName));
}

protected static string? GetAppExecLinkPath()
{
string localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
if (localAppDataPath is null)
{
return null;
}

string windowsAppsDir = Path.Join(localAppDataPath, "Microsoft", "WindowsApps");

if (!Directory.Exists(windowsAppsDir))
{
return null;
}

var opts = new EnumerationOptions { RecurseSubdirectories = true };

return new FileSystemEnumerable<string?>(
windowsAppsDir,
(ref FileSystemEntry entry) => entry.ToFullPath(),
opts)
{
ShouldIncludePredicate = (ref FileSystemEntry entry) =>
FileSystemName.MatchesWin32Expression("*.exe", entry.FileName) &&
(entry.Attributes & FileAttributes.ReparsePoint) != 0
}.FirstOrDefault();
}

public static IEnumerable<object[]> ResolveLinkTarget_PathToTarget_Data
{
get
Expand Down
15 changes: 15 additions & 0 deletions src/libraries/System.IO.FileSystem/tests/File/SymbolicLinks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ protected override void AssertLinkExists(FileSystemInfo link) =>
public void ResolveLinkTarget_Throws_NotExists() =>
ResolveLinkTarget_Throws_NotExists_Internal<FileNotFoundException>();

[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public void UnsupportedLink_ReturnsNull()
{
string unsupportedLinkPath = GetAppExecLinkPath();
if (unsupportedLinkPath is null)
{
return;
}

Assert.Null(File.ResolveLinkTarget(unsupportedLinkPath, false));
Assert.Null(File.ResolveLinkTarget(unsupportedLinkPath, true));
}


[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void CreateSymbolicLink_PathToTarget_RelativeToLinkPath()
{
Expand Down
18 changes: 18 additions & 0 deletions src/libraries/System.IO.FileSystem/tests/FileInfo/SymbolicLinks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ protected override void AssertLinkExists(FileSystemInfo link) =>
public void ResolveLinkTarget_Throws_NotExists() =>
ResolveLinkTarget_Throws_NotExists_Internal<FileNotFoundException>();


[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public void UnsupportedLink_ReturnsNull()
{
string unsupportedLinkPath = GetAppExecLinkPath();
if (unsupportedLinkPath is null)
{
return;
}

var info = new FileInfo(unsupportedLinkPath);

Assert.Null(info.LinkTarget);
Assert.Null(info.ResolveLinkTarget(false));
Assert.Null(info.ResolveLinkTarget(true));
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void CreateSymbolicLink_PathToTarget_RelativeToLinkPath()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,8 @@ internal static void CreateSymbolicLink(string path, string pathToTarget, bool i
// The file or directory is not a reparse point.
if ((data.dwFileAttributes & (uint)FileAttributes.ReparsePoint) == 0 ||
// Only symbolic links and mount points are supported at the moment.
((data.dwReserved0 & Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK) == 0 &&
(data.dwReserved0 & Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT) == 0))
(data.dwReserved0 != Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK &&
data.dwReserved0 != Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT))
{
return null;
}
Expand Down

0 comments on commit c7e5075

Please sign in to comment.