Fix path length 255 (dotnet/corefx#34389)
authorDan Moseley <danmose@microsoft.com>
Tue, 8 Jan 2019 18:16:06 +0000 (10:16 -0800)
committerGitHub <noreply@github.com>
Tue, 8 Jan 2019 18:16:06 +0000 (10:16 -0800)
* long name test

* typo

* typo

* Enable test as WSL fixed

* Disable test for WSL

* Test update

* Fix tests

* Properly reuse buffer length

* Fix actual bug

* Tests for create on Linux

* Extend to unix

* netfx

* Update interop file

Commit migrated from https://github.com/dotnet/corefx/commit/23521cc75428e38b8ff62cbac188c86b32184d42

src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
src/libraries/System.IO.FileSystem/tests/Enumeration/ErrorHandlingTests.netcoreapp.cs
src/libraries/System.IO.FileSystem/tests/File/Create.cs
src/libraries/System.IO.FileSystem/tests/FileStream/LockUnlock.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketOptionNameTest.cs

index c8fb2e5..fbcfcf5 100644 (file)
@@ -10,14 +10,13 @@ namespace System.IO.Enumeration
     /// Lower level view of FileSystemInfo used for processing and filtering find results.
     /// </summary>
     public unsafe ref partial struct FileSystemEntry
-    {
-        private const int FileNameBufferSize = 256;
+   {
         internal Interop.Sys.DirectoryEntry _directoryEntry;
         private FileStatus _status;
         private Span<char> _pathBuffer;
         private ReadOnlySpan<char> _fullPath;
         private ReadOnlySpan<char> _fileName;
-        private fixed char _fileNameBuffer[FileNameBufferSize];
+        private fixed char _fileNameBuffer[Interop.Sys.DirectoryEntry.NameBufferSize];
         private FileAttributes _initialAttributes;
 
         internal static FileAttributes Initialize(
@@ -94,7 +93,7 @@ namespace System.IO.Enumeration
                 {
                     fixed (char* c = _fileNameBuffer)
                     {
-                        Span<char> buffer = new Span<char>(c, FileNameBufferSize);
+                        Span<char> buffer = new Span<char>(c, Interop.Sys.DirectoryEntry.NameBufferSize);
                         _fileName = _directoryEntry.GetName(buffer);
                     }
                 }
index e4c85d8..87007cd 100644 (file)
@@ -1,7 +1,10 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.IO.Enumeration;
 using Xunit;
 
@@ -96,5 +99,39 @@ namespace System.IO.Tests
                 Assert.Equal(info.FullName, ie.DirectoryFinished);
             }
         }
+
+       [Fact]
+       public void VariableLengthFileNames_AllCreatableFilesAreEnumerable()
+       {
+           DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath());
+           var names = new List<string>();
+
+           for (int length = 1; length < 10_000; length++) // arbitrarily large limit for the test
+           {
+               string name = new string('a', length);
+               try { File.Create(Path.Join(testDirectory.FullName, name)).Dispose(); }
+               catch { break; }
+               names.Add(name);
+           }
+           Assert.InRange(names.Count, 1, int.MaxValue);
+           Assert.Equal(names.OrderBy(n => n), Directory.GetFiles(testDirectory.FullName).Select(n => Path.GetFileName(n)).OrderBy(n => n));
+       }
+
+       [Fact]
+       public void VariableLengthDirectoryNames_AllCreatableDirectoriesAreEnumerable()
+       {
+           DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath());
+           var names = new List<string>();
+
+           for (int length = 1; length < 10_000; length++) // arbitrarily large limit for the test
+           {
+               string name = new string('a', length);
+               try { Directory.CreateDirectory(Path.Join(testDirectory.FullName, name)); }
+               catch { break; }
+               names.Add(name);
+           }
+           Assert.InRange(names.Count, 1, int.MaxValue);
+           Assert.Equal(names.OrderBy(n => n), Directory.GetDirectories(testDirectory.FullName).Select(n => Path.GetFileName(n)).OrderBy(n => n));
+       }
     }
 }
index c910e73..be16528 100644 (file)
@@ -169,6 +169,33 @@ namespace System.IO.Tests
         #region PlatformSpecific
 
         [Fact]
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        public void LongDirectoryName()
+        {
+            // 255 = NAME_MAX on Linux and macOS
+            DirectoryInfo path = Directory.CreateDirectory(Path.Combine(GetTestFilePath(), new string('a', 255)));
+
+            Assert.True(Directory.Exists(path.FullName));
+            Directory.Delete(path.FullName);
+            Assert.False(Directory.Exists(path.FullName));
+        }
+
+        [Fact]
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        public void LongFileName()
+        {
+            // 255 = NAME_MAX on Linux and macOS
+            var dir = GetTestFilePath();
+            Directory.CreateDirectory(dir);
+            var path = Path.Combine(dir, new string('b', 255));
+            File.Create(path).Dispose();
+
+            Assert.True(File.Exists(path));
+            File.Delete(path);
+            Assert.False(File.Exists(path));
+        }
+
+        [Fact]
         [PlatformSpecific(CaseSensitivePlatforms)]
         public void CaseSensitive()
         {
index 2d7207e..68e7a56 100644 (file)
@@ -153,7 +153,7 @@ namespace System.IO.Tests
             }
         }
 
-        [Theory]
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // https://github.com/dotnet/corefx/issues/34397
         [InlineData(10, 0, 10, 1, 2)]
         [InlineData(10, 3, 5, 3, 5)]
         [InlineData(10, 3, 5, 3, 4)]
index 3a3b3a8..2b3ab0d 100644 (file)
@@ -232,11 +232,7 @@ namespace System.Net.Sockets.Tests
                 receiveSocket.ReceiveTimeout = 1000;
                 receiveSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(multicastAddress, interfaceIndex));
 
-                // https://github.com/Microsoft/BashOnWindows/issues/990
-                if (!PlatformDetection.IsWindowsSubsystemForLinux)
-                {
-                    sendSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, interfaceIndex);
-                }
+                sendSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, interfaceIndex);
 
                 var receiveBuffer = new byte[1024];
                 var receiveTask = receiveSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), SocketFlags.None);