Thomas Mullaly : urlmon: Improved support for determining if a URI is hierarchical or not.

Alexandre Julliard julliard at winehq.org
Fri Aug 27 11:11:17 CDT 2010


Module: wine
Branch: master
Commit: 948009872dcd322c4eeeaa55da7e2117eafa13d0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=948009872dcd322c4eeeaa55da7e2117eafa13d0

Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date:   Wed Aug 25 21:12:46 2010 -0400

urlmon: Improved support for determining if a URI is hierarchical or not.

---

 dlls/urlmon/tests/uri.c |  116 +++++++++++++++++++++++++++++++++++++++++++++++
 dlls/urlmon/uri.c       |   44 ++++++++++++------
 2 files changed, 145 insertions(+), 15 deletions(-)

diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index 11a464e..54f5ef4 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -3771,6 +3771,122 @@ static const uri_properties uri_tests[] = {
             {URL_SCHEME_FILE,S_OK,FALSE},
             {URLZONE_INVALID,E_NOTIMPL,FALSE}
         }
+    },
+    /* The backslashes after the scheme name are converted to forward slashes. */
+    {   "file:\\\\c:\\dir\\index.html", Uri_CREATE_FILE_USE_DOS_PATH, S_OK, FALSE,
+        Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH
+        |Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE
+        |Uri_HAS_SCHEME, FALSE,
+        {
+            {"file://c:\\dir\\index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"file://c:\\dir\\index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {".html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"c:\\dir\\index.html",S_OK,FALSE},
+            {"c:\\dir\\index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"file:\\\\c:\\dir\\index.html",S_OK,FALSE},
+            {"file",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {0,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_FILE,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
+    {   "file:\\\\c:/dir/index.html", 0, S_OK, FALSE,
+        Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH
+        |Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE
+        |Uri_HAS_SCHEME, FALSE,
+        {
+            {"file:///c:/dir/index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"file:///c:/dir/index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {".html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/c:/dir/index.html",S_OK,FALSE},
+            {"/c:/dir/index.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"file:\\\\c:/dir/index.html",S_OK,FALSE},
+            {"file",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {0,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_FILE,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
+    {   "http:\\\\google.com", 0, S_OK, FALSE,
+        Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|
+        Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|
+        Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
+        FALSE,
+        {
+            {"http://google.com/",S_OK,FALSE},
+            {"google.com",S_OK,FALSE},
+            {"http://google.com/",S_OK,FALSE},
+            {"google.com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"google.com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/",S_OK,FALSE},
+            {"/",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"http:\\\\google.com",S_OK,FALSE},
+            {"http",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_DNS,S_OK,FALSE},
+            {80,S_OK,FALSE},
+            {URL_SCHEME_HTTP,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
+    /* the "\\\\" aren't converted to "//" for unknown scheme types and it's considered opaque. */
+    {   "zip:\\\\google.com", 0, S_OK, FALSE,
+        Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
+        Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME|Uri_HAS_SCHEME|
+        Uri_HAS_HOST_TYPE,
+        FALSE,
+        {
+            {"zip:\\\\google.com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"zip:\\\\google.com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {".com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"\\\\google.com",S_OK,FALSE},
+            {"\\\\google.com",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"zip:\\\\google.com",S_OK,FALSE},
+            {"zip",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_UNKNOWN,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
     }
 };
 
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 530b1ad..f184aab 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -306,6 +306,33 @@ static inline BOOL is_hierarchical_scheme(URL_SCHEME type) {
            type == URL_SCHEME_RES);
 }
 
+/* Determines if the URI is hierarchical using the information already parsed into
+ * data and using the current location of parsing in the URI string.
+ *
+ * Windows considers a URI hierarchical if on of the following is true:
+ *  A.) It's a wildcard scheme.
+ *  B.) It's an implicit file scheme.
+ *  C.) It's a known hierarchical scheme and it has two '\\' after the scheme name.
+ *      (the '\\' will be converted into "//" during canonicalization).
+ *  D.) It's not a relative URI and "//" appears after the scheme name.
+ */
+static inline BOOL is_hierarchical_uri(const WCHAR **ptr, const parse_data *data) {
+    const WCHAR *start = *ptr;
+
+    if(data->scheme_type == URL_SCHEME_WILDCARD)
+        return TRUE;
+    else if(data->scheme_type == URL_SCHEME_FILE && data->has_implicit_scheme)
+        return TRUE;
+    else if(is_hierarchical_scheme(data->scheme_type) && (*ptr)[0] == '\\' && (*ptr)[1] == '\\') {
+        *ptr += 2;
+        return TRUE;
+    } else if(!data->is_relative && check_hierarchical(ptr))
+        return TRUE;
+
+    *ptr = start;
+    return FALSE;
+}
+
 /* Checks if the two Uri's are logically equivalent. It's a simple
  * comparison, since they are both of type Uri, and it can access
  * the properties of each Uri directly without the need to go
@@ -1866,17 +1893,8 @@ static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags)
 static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) {
     const WCHAR *start = *ptr;
 
-    /* Checks if the authority information needs to be parsed.
-     *
-     * Relative URI's aren't hierarchical URI's, but, they could trick
-     * "check_hierarchical" into thinking it is, so we need to explicitly
-     * make sure it's not relative. Also, if the URI is an implicit file
-     * scheme it might not contain a "//", but, it's considered hierarchical
-     * anyways. Wildcard Schemes are always considered hierarchical
-     */
-    if(data->scheme_type == URL_SCHEME_WILDCARD ||
-       (data->scheme_type == URL_SCHEME_FILE && is_implicit_file_path(*ptr)) ||
-       (!data->is_relative && check_hierarchical(ptr))) {
+    /* Checks if the authority information needs to be parsed. */
+    if(is_hierarchical_uri(ptr, data)) {
         /* Only treat it as a hierarchical URI if the scheme_type is known or
          * the Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is not set.
          */
@@ -1885,10 +1903,6 @@ static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) {
             TRACE("(%p %p %x): Treating URI as an hierarchical URI.\n", ptr, data, flags);
             data->is_opaque = FALSE;
 
-            if(data->scheme_type == URL_SCHEME_FILE)
-                /* Skip past the "//" after the scheme (if any). */
-                check_hierarchical(ptr);
-
             /* TODO: Handle hierarchical URI's, parse authority then parse the path. */
             if(!parse_authority(ptr, data, flags))
                 return FALSE;




More information about the wine-cvs mailing list