[release/6.0] Fix detection of unsupported links (#58399)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Wed, 8 Sep 2021 04:45:29 +0000 (22:45 -0600)
committerGitHub <noreply@github.com>
Wed, 8 Sep 2021 04:45:29 +0000 (22:45 -0600)
* Fix detection of unsupported links

* Add Directory.Exists check

* Fix CI issue caused by local testing code

Co-authored-by: David Cantu <dacantu@microsoft.com>
src/libraries/System.IO.FileSystem/tests/Base/SymbolicLinks/BaseSymbolicLinks.FileSystem.cs
src/libraries/System.IO.FileSystem/tests/File/SymbolicLinks.cs
src/libraries/System.IO.FileSystem/tests/FileInfo/SymbolicLinks.cs
src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs

index 9f61e73..e3b9027 100644 (file)
@@ -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
@@ -482,6 +484,34 @@ namespace System.IO.Tests
             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
index 4c41fa7..e879cb3 100644 (file)
@@ -45,6 +45,21 @@ namespace System.IO.Tests
         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()
         {
index fa334dd..914edd0 100644 (file)
@@ -41,6 +41,24 @@ namespace System.IO.Tests
         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()
         {
index d2bde47..223117e 100644 (file)
@@ -556,8 +556,8 @@ namespace System.IO
             // 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;
             }