Thomas Mullaly : urlmon: Implemented a fragment parser.

Alexandre Julliard julliard at winehq.org
Mon Aug 16 12:25:01 CDT 2010


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

Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date:   Thu Jul 29 16:36:39 2010 -0400

urlmon: Implemented a fragment parser.

---

 dlls/urlmon/tests/uri.c |   34 +++++++++++++++++++++++++++++++++-
 dlls/urlmon/uri.c       |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index ab0125d..196e4d8 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -3160,6 +3160,36 @@ static const uri_properties uri_tests[] = {
             {URL_SCHEME_HTTP,S_OK,FALSE},
             {URLZONE_INVALID,E_NOTIMPL,FALSE},
         }
+    },
+    /* Unknown scheme types can have invalid % encoded data in fragments. */
+    {   "zip://www.winehq.org/tests/#Te%xx", 0, S_OK, FALSE,
+        Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
+        Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
+        Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
+        TRUE,
+        {
+            {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE},
+            {"www.winehq.org",S_OK,FALSE},
+            {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE},
+            {"winehq.org",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"#Te%xx",S_OK,TRUE},
+            {"www.winehq.org",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/tests/",S_OK,FALSE},
+            {"/tests/",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"zip://www.winehq.org/tests/#Te%xx",S_OK,FALSE},
+            {"zip",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_DNS,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_UNKNOWN,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE},
+        }
     }
 };
 
@@ -3214,7 +3244,9 @@ static const invalid_uri invalid_uri_tests[] = {
     {"news:test%XX",0,FALSE},
     {"mailto:wine at winehq%G8.com",0,FALSE},
     /* Known scheme types can't have invalid % encoded data in query string. */
-    {"http://google.com/?query=te%xx",0,FALSE}
+    {"http://google.com/?query=te%xx",0,FALSE},
+    /* Invalid % encoded data in fragment of know scheme type. */
+    {"ftp://google.com/#Test%xx",0,FALSE}
 };
 
 typedef struct _uri_equality {
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 51e58d5..ecf6922 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -126,6 +126,9 @@ typedef struct {
 
     const WCHAR     *query;
     DWORD           query_len;
+
+    const WCHAR     *fragment;
+    DWORD           fragment_len;
 } parse_data;
 
 static const CHAR hexDigits[] = "0123456789ABCDEF";
@@ -1783,6 +1786,45 @@ static BOOL parse_query(const WCHAR **ptr, parse_data *data, DWORD flags) {
     return TRUE;
 }
 
+/* Attempts to parse the fragment from the URI.
+ *
+ * NOTES:
+ *  If NO_DECODE_EXTRA_INFO flag is set, then invalid percent encoded
+ *  data is allowed appear in the query string. For unknown scheme types
+ *  invalid percent encoded data is allowed to appear reguardless.
+ */
+static BOOL parse_fragment(const WCHAR **ptr, parse_data *data, DWORD flags) {
+    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
+
+    if(**ptr != '#') {
+        TRACE("(%p %p %x): URI didn't contain a fragment.\n", ptr, data, flags);
+        return TRUE;
+    }
+
+    data->fragment = *ptr;
+
+    ++(*ptr);
+    while(**ptr) {
+        if(**ptr == '%' && known_scheme &&
+           !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
+            if(!check_pct_encoded(ptr)) {
+                *ptr = data->fragment;
+                data->fragment = NULL;
+                return FALSE;
+            } else
+                continue;
+        }
+
+        ++(*ptr);
+    }
+
+    data->fragment_len = *ptr - data->fragment;
+
+    TRACE("(%p %p %x): Parsed fragment %s len=%d\n", ptr, data, flags,
+        debugstr_wn(data->fragment, data->fragment_len), data->fragment_len);
+    return TRUE;
+}
+
 /* Parses and validates the components of the specified by data->uri
  * and stores the information it parses into 'data'.
  *
@@ -1806,7 +1848,8 @@ static BOOL parse_uri(parse_data *data, DWORD flags) {
     if(!parse_query(pptr, data, flags))
         return FALSE;
 
-    /* TODO: Parse fragment (if the URI has one). */
+    if(!parse_fragment(pptr, data, flags))
+        return FALSE;
 
     TRACE("(%p %x): FINISHED PARSING URI.\n", data, flags);
     return TRUE;




More information about the wine-cvs mailing list