Thomas Mullaly : urlmon: Added a stub implementation for parsing the hier-part of a URI.

Alexandre Julliard julliard at winehq.org
Thu Jul 22 12:09:31 CDT 2010


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

Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date:   Fri Jun 11 20:19:35 2010 -0400

urlmon: Added a stub implementation for parsing the hier-part of a URI.

---

 dlls/urlmon/tests/uri.c |   30 ++++++++++++++++
 dlls/urlmon/uri.c       |   86 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+), 0 deletions(-)

diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index 07b22cc..d674925 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -823,6 +823,36 @@ static const uri_properties uri_tests[] = {
             {URL_SCHEME_WILDCARD,S_OK,FALSE},
             {URLZONE_INVALID,E_NOTIMPL,FALSE}
         }
+    },
+    /* URI is considered opaque since CREATE_NO_CRACK_UNKNOWN_SCHEMES is set and its an unknown scheme. */
+    {   "zip://google.com", Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, 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_HOST_TYPE|Uri_HAS_SCHEME_NAME|
+        Uri_HAS_SCHEME,
+        TRUE,
+        {
+            {"zip:/.//google.com",S_OK,TRUE},
+            {"",S_FALSE,TRUE},
+            {"zip:/.//google.com",S_OK,TRUE},
+            {"",S_FALSE,TRUE},
+            {".com",S_OK,TRUE},
+            {"",S_FALSE,TRUE},
+            {"",S_FALSE,TRUE},
+            {"",S_FALSE,TRUE},
+            {"/.//google.com",S_OK,TRUE},
+            {"/.//google.com",S_OK,TRUE},
+            {"",S_FALSE,TRUE},
+            {"zip://google.com",S_OK,FALSE},
+            {"zip",S_OK,FALSE},
+            {"",S_FALSE,TRUE},
+            {"",S_FALSE,TRUE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,TRUE},
+            {0,S_FALSE,TRUE},
+            {URL_SCHEME_UNKNOWN,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
     }
 };
 
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 06f8872..d8ff2cb 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -49,6 +49,8 @@ typedef struct {
     BSTR            uri;
 
     BOOL            is_relative;
+    BOOL            is_opaque;
+    BOOL            has_implicit_scheme;
 
     const WCHAR     *scheme;
     DWORD           scheme_len;
@@ -104,6 +106,25 @@ static inline BOOL is_implicit_file_path(const WCHAR *str) {
     return FALSE;
 }
 
+/* Checks if the URI is a hierarchical URI. A hierarchical
+ * URI is one that has "//" after the scheme.
+ */
+static BOOL check_hierarchical(const WCHAR **ptr) {
+    const WCHAR *start = *ptr;
+
+    if(**ptr != '/')
+        return FALSE;
+
+    ++(*ptr);
+    if(**ptr != '/') {
+        *ptr = start;
+        return FALSE;
+    }
+
+    ++(*ptr);
+    return TRUE;
+}
+
 /* Tries to parse the scheme name of the URI.
  *
  * scheme = ALPHA *(ALPHA | NUM | '+' | '-' | '.') as defined by RFC 3896.
@@ -195,6 +216,8 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
         if(flags & Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME) {
             data->scheme = fileW;
             data->scheme_len = lstrlenW(fileW);
+            data->has_implicit_scheme = TRUE;
+
             TRACE("(%p %p %x): URI is an implicit file path.\n", ptr, data, flags);
         } else {
             /* Window's does not consider anything that can implicitly be a file
@@ -213,6 +236,7 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
         if(flags & Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME) {
             data->scheme = wildcardW;
             data->scheme_len = lstrlenW(wildcardW);
+            data->has_implicit_scheme = TRUE;
 
             TRACE("(%p %p %x): URI is an implicit wildcard scheme.\n", ptr, data, flags);
         } else if (flags & Uri_CREATE_ALLOW_RELATIVE) {
@@ -235,6 +259,65 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
     return TRUE;
 }
 
+/* Determines how the URI should be parsed after the scheme information.
+ *
+ * If the scheme is followed, by "//" then, it is treated as an hierarchical URI
+ * which then the authority and path information will be parsed out. Otherwise, the
+ * URI will be treated as an opaque URI which the authority information is not parsed
+ * out.
+ *
+ * RFC 3896 defenition of hier-part:
+ *
+ * hier-part   = "//" authority path-abempty
+ *                 / path-absolute
+ *                 / path-rootless
+ *                 / path-empty
+ *
+ * MSDN opaque URI definition:
+ *  scheme ":" path [ "#" fragment ]
+ *
+ * NOTES:
+ *  If the URI is of an unknown scheme type and has a "//" following the scheme then it
+ *  is treated as a hierarchical URI, but, if the CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is
+ *  set then it is considered an opaque URI reguardless of what follows the scheme information
+ *  (per MSDN documentation).
+ */
+static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) {
+    /* 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 ||
+       (!data->is_relative && check_hierarchical(ptr))) {
+        /* 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.
+         */
+        if(data->scheme_type != URL_SCHEME_UNKNOWN ||
+           !(flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES)) {
+            TRACE("(%p %p %x): Treating URI as an hierarchical URI.\n", ptr, data, flags);
+            data->is_opaque = FALSE;
+
+            /* TODO: Handle hierarchical URI's, parse authority then parse the path. */
+            return TRUE;
+        }
+    }
+
+    /* If it reaches here, then the URI will be treated as an opaque
+     * URI.
+     */
+
+    TRACE("(%p %p %x): Treating URI as an opaque URI.\n", ptr, data, flags);
+
+    data->is_opaque = TRUE;
+    /* TODO: Handle opaque URI's, parse path. */
+    return TRUE;
+}
+
 /* Parses and validates the components of the specified by data->uri
  * and stores the information it parses into 'data'.
  *
@@ -252,6 +335,9 @@ static BOOL parse_uri(parse_data *data, DWORD flags) {
     if(!parse_scheme(pptr, data, flags))
         return FALSE;
 
+    if(!parse_hierpart(pptr, data, flags))
+        return FALSE;
+
     TRACE("(%p %x): FINISHED PARSING URI.\n", data, flags);
     return TRUE;
 }




More information about the wine-cvs mailing list