Fixes to System.Uri wrt 'file' scheme
authorSebastien Pouliot <sebastien@ximian.com>
Thu, 16 Sep 2010 14:37:50 +0000 (10:37 -0400)
committerSebastien Pouliot <sebastien@ximian.com>
Thu, 16 Sep 2010 21:32:19 +0000 (17:32 -0400)
* System/Uri.cs: Fix 'file' URI since they can't have a query

* Test/System/UriTest2.cs: Add new test case for 'file' URIs and
some asserts on "custom" URI (which do support queries)

mcs/class/System/System/Uri.cs
mcs/class/System/Test/System/UriTest2.cs

index d086c641f0195b8930ab56dc363de1c8764f42ad..17003a940abd2517bb4de70c1e98d5ebcb46fb65 100644 (file)
@@ -1302,6 +1302,11 @@ namespace System {
                                throw new UriFormatException (s);
                }
 
+               private bool SupportsQuery ()
+               {
+                       return ((scheme != Uri.UriSchemeNntp) && (scheme != Uri.UriSchemeFtp) && (scheme != Uri.UriSchemeFile));
+               }
+
                //
                // This parse method will not throw exceptions on failure
                //
@@ -1412,8 +1417,8 @@ namespace System {
                                return null;
                        }
 
-                       // special case: there is no query part for 'nntp' and 'ftp' but there is an host, port, user...
-                       if ((scheme != Uri.UriSchemeNntp) && (scheme != Uri.UriSchemeFtp)) {
+                       // special case: there is no query part for 'nntp', 'file' and 'ftp' but there is an host, port, user...
+                       if (SupportsQuery ()) {
                                // 6 query
                                pos = uriString.IndexOf ('?', startpos, endpos-startpos);
                                if (pos != -1) {
@@ -1470,31 +1475,24 @@ namespace System {
                        }
 
                        // 5 path
-                       if ((scheme == Uri.UriSchemeNntp) || (scheme == Uri.UriSchemeFtp)) {
+                       if (unixAbsPath) {
+                               pos = -1;
+                       } else {
                                pos = uriString.IndexOf ('/', startpos, endpos - startpos);
-                               if (pos != -1) {
-                                       path = uriString.Substring (pos, endpos - pos);
-                                       if (scheme == Uri.UriSchemeFtp)
+                               if (pos == -1 && windowsFilePath)
+                                       pos = uriString.IndexOf ('\\', startpos, endpos - startpos);
+                       }
+                       if (pos != -1) {
+                               path = uriString.Substring (pos, endpos - pos);
+                               if (!SupportsQuery ()) {
+                                       if (scheme != Uri.UriSchemeNntp)
                                                path = path.Replace ('\\', '/');
                                        path = EscapeString (path, EscapeNews);
-                                       endpos = pos;
                                }
+                               endpos = pos;
                        } else {
-                               if (unixAbsPath) {
-                                       pos = -1;
-                               } else {
-                                       pos = uriString.IndexOf ('/', startpos, endpos - startpos);
-                                       if (pos == -1 && windowsFilePath)
-                                               pos = uriString.IndexOf ('\\', startpos, endpos - startpos);
-                               }
-
-                               if (pos == -1) {
-                                       if (scheme != Uri.UriSchemeMailto)
-                                               path = "/";
-                               } else {
-                                       path = uriString.Substring (pos, endpos - pos);
-                                       endpos = pos;
-                               }
+                               if (scheme != Uri.UriSchemeMailto)
+                                       path = "/";
                        }
 
                        // 4.a user info
index e4e70e0c87da9b2ce8bf94dd6559c6964650ab1e..ccf1a0edf3f5adeeb3302fa9169b3530c13aca96 100644 (file)
@@ -724,6 +724,16 @@ TextWriter sw = Console.Out;
                        Assert.AreEqual (String.Empty, uri.Host, "4/Host");
                        Assert.AreEqual ("//host/dir/subdir/file", uri.AbsolutePath, "4/AbsolutePath");
                        Assert.AreEqual ("//host/dir/subdir/file", uri.LocalPath, "4/LocalPath");
+
+                       // query and fragment
+                       uri = new Uri ("mono://host/dir/subdir/file?query#fragment");
+                       Assert.AreEqual ("/dir/subdir/file", uri.AbsolutePath, "qf.AbsolutePath");
+                       Assert.AreEqual ("?query", uri.Query, "qf.Query");
+                       Assert.AreEqual ("#fragment", uri.Fragment, "qf.Fragment");
+
+                       // special characters
+                       uri = new Uri ("mono://host/<>%\"{}|\\^`;/:@&=+$,[]#abc");
+                       Assert.AreEqual ("/%3C%3E%25%22%7B%7D%7C/%5E%60;/:@&=+$,%5B%5D", uri.AbsolutePath, "Special");
                }
 
                [Test]
@@ -841,5 +851,39 @@ TextWriter sw = Console.Out;
                        Assert.AreEqual ("/%3C%3E%25%22%7B%7D%7C/%5E%60;/%3F:@&=+$,%5B%5D", uri.AbsolutePath, "Special");
                        Assert.AreEqual ("#abc", uri.Fragment, "Special/Fragment");
                }
+
+               [Test]
+               public void FileScheme ()
+               {
+                       Uri uri = new Uri ("file://host/dir/subdir/file?this-is-not-a-query#but-this-is-a-fragment");
+                       Assert.AreEqual ("/dir/subdir/file%3Fthis-is-not-a-query", uri.AbsolutePath, "AbsolutePath");
+                       Assert.AreEqual ("file://host/dir/subdir/file%3Fthis-is-not-a-query#but-this-is-a-fragment", uri.AbsoluteUri, "AbsoluteUri");
+                       Assert.AreEqual ("host", uri.Authority, "Authority");
+                       Assert.AreEqual ("host", uri.DnsSafeHost, "DnsSafeHost");
+                       Assert.AreEqual ("#but-this-is-a-fragment", uri.Fragment, "Fragment");
+                       Assert.AreEqual ("host", uri.Host, "Host");
+                       Assert.AreEqual (UriHostNameType.Dns, uri.HostNameType, "HostNameType");
+                       Assert.IsTrue (uri.IsAbsoluteUri, "IsAbsoluteUri");
+                       Assert.IsTrue (uri.IsDefaultPort, "IsDefaultPort");
+                       Assert.IsTrue (uri.IsFile, "IsFile");
+                       Assert.IsFalse (uri.IsLoopback, "IsLoopback");
+                       Assert.IsTrue (uri.IsUnc, "IsUnc");
+                       Assert.AreEqual (isWin32 ? "\\\\host\\dir\\subdir\\file?this-is-not-a-query" : "/dir/subdir/file?this-is-not-a-query", uri.LocalPath, "LocalPath");
+                       Assert.AreEqual ("file://host/dir/subdir/file?this-is-not-a-query#but-this-is-a-fragment", uri.OriginalString, "OriginalString");
+                       Assert.AreEqual ("/dir/subdir/file%3Fthis-is-not-a-query", uri.PathAndQuery, "PathAndQuery");
+                       Assert.AreEqual (-1, uri.Port, "Port");
+                       Assert.AreEqual (String.Empty, uri.Query, "Query");
+                       Assert.AreEqual ("file", uri.Scheme, "Scheme");
+                       Assert.AreEqual ("/", uri.Segments [0], "Segments [0]");
+                       Assert.AreEqual ("dir/", uri.Segments [1], "Segments [1]");
+                       Assert.AreEqual ("subdir/", uri.Segments [2], "Segments [2]");
+                       Assert.AreEqual ("file%3Fthis-is-not-a-query", uri.Segments [3], "Segments [3]");
+                       Assert.IsFalse (uri.UserEscaped, "UserEscaped");
+                       Assert.AreEqual (String.Empty, uri.UserInfo, "UserInfo");
+
+                       // special characters
+                       uri = new Uri ("file://host/<>%\"{}|\\^`;/?:@&=+$,[]#abc");
+                       Assert.AreEqual ("/%3C%3E%25%22%7B%7D%7C/%5E%60;/%3F:@&=+$,%5B%5D", uri.AbsolutePath, "Special");
+               }
        }\r
 }\r