Keep "ftp://a.b/%2fcd" urls unmolested
authorRaja R Harinath <harinath@hurrynot.org>
Sat, 17 Apr 2010 10:33:03 +0000 (10:33 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Sat, 17 Apr 2010 10:33:03 +0000 (10:33 -0000)
* System/Uri.cs (CompactEscaped): New.  Check if scheme allows escaped
path characters are compacted (list of schemes obtained from MSDN).
(Reduce): Add argument that is set if escaped characters need to
be compacted.
* Tests/System/UriTest.cs (FtpRootPath): New.  Check that ftp root paths are
unmolested.

svn path=/trunk/mcs/; revision=155670

mcs/class/System/System/ChangeLog
mcs/class/System/System/Uri.cs
mcs/class/System/Test/System/ChangeLog
mcs/class/System/Test/System/UriTest.cs

index 62df47af16a4301a294012337164f6f7b2a853df..3b9dcdc2fedd1565641f33f5fdc9a0acd4ff74f5 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       Keep "ftp://a.b/%2fcd" urls unmolested
+       * Uri.cs (CompactEscaped): New.  Check if scheme allows escaped
+       path characters are compacted (list of schemes obtained from MSDN).
+       (Reduce): Add argument that is set if escaped characters need to
+       be compacted.
+
 2010-03-20  Miguel de Icaza  <miguel@novell.com>
 
        * Uri.cs: Drop pre-2.0 support
index 591c197b5d6df094fc0e7739cb065f3bfe451c78..6f435c7fb8e33e1f07e7014d1e74bdff743c5bdb 100644 (file)
@@ -863,7 +863,7 @@ namespace System {
                                                sb.Append (path);
                                                break;
                                        default:
-                                               sb.Append (Reduce (path));
+                                               sb.Append (Reduce (path, CompactEscaped (Scheme)));
                                                break;
                                        }
                                }
@@ -1442,7 +1442,7 @@ namespace System {
                        host = uriString;
 
                        if (unixAbsPath) {
-                               path = Reduce ('/' + uriString);
+                               path = Reduce ('/' + uriString, true);
                                host = String.Empty;
                        } else if (host.Length == 2 && host [1] == ':') {
                                // windows filepath
@@ -1486,47 +1486,67 @@ namespace System {
                        if ((scheme != Uri.UriSchemeMailto) &&
                                        (scheme != Uri.UriSchemeNews) &&
                                        (scheme != Uri.UriSchemeFile)) {
-                               path = Reduce (path);
+                               path = Reduce (path, CompactEscaped (scheme));
                        }
 
                        return null;
                }
 
-               private static string Reduce (string path)
+               private static bool CompactEscaped (string scheme)
+               {
+                       switch (scheme) {
+                       case "file":
+                       case "http":
+                       case "https":
+                       case "net.pipe":
+                       case "net.tcp":
+                               return true;
+                       }
+                       return false;
+               }
+
+               // This is called "compacting" in the MSDN documentation
+               private static string Reduce (string path, bool compact_escaped)
                {
                        // quick out, allocation-free, for a common case
                        if (path == "/")
                                return path;
 
-                       // replace '\', %5C ('\') and %2f ('/') into '/'
-                       // other escaped values seems to survive this step
                        StringBuilder res = new StringBuilder();
-                       for (int i=0; i < path.Length; i++) {
-                               char c = path [i];
-                               switch (c) {
-                               case '\\':
-                                       res.Append ('/');
-                                       break;
-                               case '%':
-                                       if (i < path.Length - 2) {
-                                               char c1 = path [i + 1];
-                                               char c2 = Char.ToUpper (path [i + 2]);
-                                               if (((c1 == '2') && (c2 == 'F')) || ((c1 == '5') && (c2 == 'C'))) {
-                                                       res.Append ('/');
-                                                       i += 2;
+
+                       if (compact_escaped) {
+                               // replace '\', %5C ('\') and %2f ('/') into '/'
+                               // other escaped values seems to survive this step
+                               for (int i=0; i < path.Length; i++) {
+                                       char c = path [i];
+                                       switch (c) {
+                                       case '\\':
+                                               res.Append ('/');
+                                               break;
+                                       case '%':
+                                               if (i < path.Length - 2) {
+                                                       char c1 = path [i + 1];
+                                                       char c2 = Char.ToUpper (path [i + 2]);
+                                                       if (((c1 == '2') && (c2 == 'F')) || ((c1 == '5') && (c2 == 'C'))) {
+                                                               res.Append ('/');
+                                                               i += 2;
+                                                       } else {
+                                                               res.Append (c);
+                                                       }
                                                } else {
                                                        res.Append (c);
                                                }
-                                       } else {
+                                               break;
+                                       default:
                                                res.Append (c);
+                                               break;
                                        }
-                                       break;
-                               default:
-                                       res.Append (c);
-                                       break;
                                }
+                               path = res.ToString ();
+                       } else {
+                               path = path.Replace ('\\', '/');
                        }
-                       path = res.ToString ();
+
                        ArrayList result = new ArrayList ();
 
                        for (int startpos = 0; startpos < path.Length; ) {
index 4728ac5b7b1cb4c4027bea43393e1dfaf5497d12..daae27e1f2b1e1f0582475f2fab9172a54f0db24 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-17  Raja R Harinath  <harinath@hurrynot.org>
+
+       * UriTest.cs (FtpRootPath): New.  Check that ftp root paths are
+       unmolested.
+
 2010-01-27  Carlos Alberto Cortez <calberto.cortez@gmail.com>
 
        * UriTest.cs: added an assertion in the IsWellFormedOriginalString
index 2c5de023b61609bbd5e2c5517416fdfb51830cd2..5f3eb5147d64258670694068efdd2b5fbf0a76dd 100644 (file)
@@ -1714,6 +1714,18 @@ namespace MonoTests.System
                        Console.WriteLine ("");
                }
 
+               [Test]
+               public void FtpRootPath ()
+               {
+                       Uri u = new Uri ("ftp://a.b/%2fabc/def");
+                       string p = u.PathAndQuery;
+                       Assert.AreEqual ("/%2fabc/def", p);
+                       p = Uri.UnescapeDataString (p).Substring (1);
+                       Assert.AreEqual ("/abc/def", p);
+                       u = new Uri (new Uri ("ftp://a.b/c/d/e/f"), p);
+                       Assert.AreEqual ("/abc/def", u.PathAndQuery);
+               }
+
 //BNC#533572
 #if NET_2_0
                [Test]