Thomas Mullaly : urlmon: Added parser for registered host names.

Alexandre Julliard julliard at winehq.org
Mon Jul 26 13:22:30 CDT 2010


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

Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date:   Wed Jun 30 21:27:28 2010 -0400

urlmon: Added parser for registered host names.

---

 dlls/urlmon/uri.c |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 82f44bf..da1d379 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -714,6 +714,91 @@ static BOOL parse_ipv4address(const WCHAR **ptr, parse_data *data, DWORD flags)
     return TRUE;
 }
 
+/* Attempts to parse the reg-name from the URI.
+ *
+ * reg-name = *( unreserved / pct-encoded / sub-delims )
+ *
+ * NOTE:
+ *  Windows allows everything, but, the characters in "auth_delims" and ':'
+ *  to appear in a reg-name.
+ *
+ *  Windows doesn't like host names which start with '[' and end with ']'
+ *  and don't contain a valid IP literal address in between them.
+ *
+ *  On Windows if an '[' is encountered in the host name the ':' no longer
+ *  counts as a delimiter until you reach the next ']' or an "authority delimeter".
+ *
+ *  A reg-name CAN be empty.
+ */
+static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags) {
+    const BOOL has_start_bracket = **ptr == '[';
+    const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
+    BOOL inside_brackets = has_start_bracket;
+
+    /* We have to be careful with file schemes. */
+    if(data->scheme_type == URL_SCHEME_FILE) {
+        /* This is because an implicit file scheme could be "C:\\test" and it
+         * would trick this function into thinking the host is "C", when after
+         * canonicalization the host would end up being an empty string.
+         */
+        if(is_alpha(**ptr) && *(*ptr+1) == ':') {
+            /* Regular old drive paths don't have a host type (or host name). */
+            data->host_type = Uri_HOST_UNKNOWN;
+            data->host = *ptr;
+            data->host_len = 0;
+            return TRUE;
+        } else if(**ptr == '\\' && *(*ptr+1) == '\\')
+            /* Skip past the "\\" of a UNC path. */
+            *ptr += 2;
+    }
+
+    data->host = *ptr;
+
+    while(!is_auth_delim(**ptr, known_scheme)) {
+        if(**ptr == ':') {
+            /* We can ignore ':' if were inside brackets.*/
+            if(!inside_brackets)
+                break;
+        } else if(**ptr == '%' && known_scheme) {
+            /* Has to be a legit % encoded value. */
+            if(!check_pct_encoded(ptr)) {
+                *ptr = data->host;
+                data->host = NULL;
+                return FALSE;
+            } else
+                continue;
+        } else if(**ptr == ']')
+            inside_brackets = FALSE;
+        else if(**ptr == '[')
+            inside_brackets = TRUE;
+
+        ++(*ptr);
+    }
+
+    if(has_start_bracket) {
+        /* Make sure the last character of the host wasn't a ']'. */
+        if(*(*ptr-1) == ']') {
+            TRACE("(%p %p %x): Expected an IP literal inside of the host\n",
+                ptr, data, flags);
+            *ptr = data->host;
+            data->host = NULL;
+            return FALSE;
+        }
+    }
+
+    data->host_len = *ptr - data->host;
+
+    /* If the host is empty, then it's an unknown host type. */
+    if(data->host_len == 0)
+        data->host_type = Uri_HOST_UNKNOWN;
+    else
+        data->host_type = Uri_HOST_DNS;
+
+    TRACE("(%p %p %x): Parsed reg-name. host=%s len=%d\n", ptr, data, flags,
+        debugstr_wn(data->host, data->host_len), data->host_len);
+    return TRUE;
+}
+
 /* Attempts to parse an IPv6 address out of the URI.
  *
  * IPv6address =                               6( h16 ":" ) ls32
@@ -958,8 +1043,11 @@ static BOOL parse_ip_literal(const WCHAR **ptr, parse_data *data, DWORD flags) {
 static BOOL parse_host(const WCHAR **ptr, parse_data *data, DWORD flags) {
     if(!parse_ip_literal(ptr, data, flags)) {
         if(!parse_ipv4address(ptr, data, flags)) {
-            WARN("(%p %p %x): reg-name parsing is not supported yet.\n",
-                ptr, data, flags);
+            if(!parse_reg_name(ptr, data, flags)) {
+                TRACE("(%p %p %x): Malformed URI, Unknown host type.\n",
+                    ptr, data, flags);
+                return FALSE;
+            }
         }
     }
 




More information about the wine-cvs mailing list