Browse Source

Path.CleanPath() does not always replace AltDirectorySeparatorChar

If sub == 0, i.e. there are no repeated separators, this method just returns
the input string. On Windows, where DirectorySeparatorChar (\) is different
from AltDirectorySeparatorChar (/), this means that the call

    Path.GetDirectoryName ("foo/bar/dingus")

won't return "foo\bar" as .NET would but rather returns "foo/bar".

This patch makes sure the '/' -> '\' conversion is run when
AltDirectorySeparatorChar characters have been seen in the input string, even
if sub == 0.

PathTest.GetDirectoryName() triggered this bug.
Niklas Therning 9 years ago
parent
commit
3b1ebefb7b
2 changed files with 11 additions and 1 deletions
  1. 4 1
      mcs/class/corlib/System.IO/Path.cs
  2. 7 0
      mcs/class/corlib/Test/System.IO/PathTest.cs

+ 4 - 1
mcs/class/corlib/System.IO/Path.cs

@@ -140,6 +140,7 @@ namespace System.IO {
 		{
 			int l = s.Length;
 			int sub = 0;
+			int alt = 0;
 			int start = 0;
 
 			// Host prefix?
@@ -158,6 +159,8 @@ namespace System.IO {
 				
 				if (c != DirectorySeparatorChar && c != AltDirectorySeparatorChar)
 					continue;
+				if (DirectorySeparatorChar != AltDirectorySeparatorChar && c == AltDirectorySeparatorChar)
+					alt++;
 				if (i+1 == l)
 					sub++;
 				else {
@@ -167,7 +170,7 @@ namespace System.IO {
 				}
 			}
 
-			if (sub == 0)
+			if (sub == 0 && alt == 0)
 				return s;
 
 			char [] copy = new char [l-sub];

+ 7 - 0
mcs/class/corlib/Test/System.IO/PathTest.cs

@@ -37,6 +37,7 @@ namespace MonoTests.System.IO
 		static string path3;
 		static OsType OS;
 		static char DSC = Path.DirectorySeparatorChar;
+		static char ADSC = Path.AltDirectorySeparatorChar;
 
 		[SetUp]
 		public void SetUp ()
@@ -359,6 +360,12 @@ namespace MonoTests.System.IO
 			}
 		}
 
+		[Test]
+		public void GetDirectoryName_Replaces_AltDirectorySeparatorChar ()
+		{
+			Assert.AreEqual ($"foo{DSC}bar", Path.GetDirectoryName ($"foo{ADSC}bar{ADSC}dingus"), "#1");
+		}
+
 		[Test]
 		public void GetExtension ()
 		{