Thomas Mullaly : urlmon: Improve IUri support of res URIs.

Alexandre Julliard julliard at winehq.org
Tue Nov 9 13:13:22 CST 2010


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

Author: Thomas Mullaly <thomas.mullaly at gmail.com>
Date:   Sun Nov  7 11:09:49 2010 -0500

urlmon: Improve IUri support of res URIs.

---

 dlls/urlmon/tests/uri.c |  113 ++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/urlmon/uri.c       |   24 +++++++---
 2 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index cd6e57c..b11a3a0 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -3849,6 +3849,110 @@ static const uri_properties uri_tests[] = {
             {URL_SCHEME_HTTP,S_OK,FALSE},
             {URLZONE_INVALID,E_NOTIMPL,FALSE}
         }
+    },
+    /* For res URIs the host is everything up until the first '/'. */
+    {   "res://C:\\dir\\file.exe/DATA/test.html", 0, S_OK, FALSE,
+        {
+            {"res://C:\\dir\\file.exe/DATA/test.html",S_OK,FALSE},
+            {"C:\\dir\\file.exe",S_OK,FALSE},
+            {"res://C:\\dir\\file.exe/DATA/test.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {".html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"C:\\dir\\file.exe",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/DATA/test.html",S_OK,FALSE},
+            {"/DATA/test.html",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"res://C:\\dir\\file.exe/DATA/test.html",S_OK,FALSE},
+            {"res",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_RES,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
+    /* Res URI can contain a '|' in the host name. */
+    {   "res://c:\\di|r\\file.exe/test", 0, S_OK, FALSE,
+        {
+            {"res://c:\\di|r\\file.exe/test",S_OK,FALSE},
+            {"c:\\di|r\\file.exe",S_OK,FALSE},
+            {"res://c:\\di|r\\file.exe/test",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"c:\\di|r\\file.exe",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/test",S_OK,FALSE},
+            {"/test",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"res://c:\\di|r\\file.exe/test",S_OK,FALSE},
+            {"res",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_RES,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE},
+        }
+    },
+    /* Res URIs can have invalid percent encoded values. */
+    {   "res://c:\\dir%xx\\file.exe/test", 0, S_OK, FALSE,
+        {
+            {"res://c:\\dir%xx\\file.exe/test",S_OK,FALSE},
+            {"c:\\dir%xx\\file.exe",S_OK,FALSE},
+            {"res://c:\\dir%xx\\file.exe/test",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"c:\\dir%xx\\file.exe",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/test",S_OK,FALSE},
+            {"/test",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"res://c:\\dir%xx\\file.exe/test",S_OK,FALSE},
+            {"res",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_RES,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
+    },
+    /* Res doesn't get forbidden characters percent encoded in it's path. */
+    {   "res://c:\\test/tes<|>t", 0, S_OK, FALSE,
+        {
+            {"res://c:\\test/tes<|>t",S_OK,FALSE},
+            {"c:\\test",S_OK,FALSE},
+            {"res://c:\\test/tes<|>t",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE},
+            {"c:\\test",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"/tes<|>t",S_OK,FALSE},
+            {"/tes<|>t",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"res://c:\\test/tes<|>t",S_OK,FALSE},
+            {"res",S_OK,FALSE},
+            {"",S_FALSE,FALSE},
+            {"",S_FALSE,FALSE}
+        },
+        {
+            {Uri_HOST_UNKNOWN,S_OK,FALSE},
+            {0,S_FALSE,FALSE},
+            {URL_SCHEME_RES,S_OK,FALSE},
+            {URLZONE_INVALID,E_NOTIMPL,FALSE}
+        }
     }
 };
 
@@ -3913,7 +4017,14 @@ static const invalid_uri invalid_uri_tests[] = {
     {"file://c:\\test\"test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
     {"file:c:\\test<test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
     {"file:c:\\test>test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
-    {"file:c:\\test\"test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE}
+    {"file:c:\\test\"test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
+    /* res URIs aren't allowed to have forbidden dos path characters in the
+     * hostname.
+     */
+    {"res://c:\\te<st\\test/test",0,FALSE},
+    {"res://c:\\te>st\\test/test",0,FALSE},
+    {"res://c:\\te\"st\\test/test",0,FALSE},
+    {"res://c:\\test/te%xxst",0,FALSE}
 };
 
 typedef struct _uri_equality {
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 97268a7..6e4ed06 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -1552,8 +1552,11 @@ static BOOL parse_ipv4address(const WCHAR **ptr, parse_data *data, DWORD flags)
 static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
     const BOOL has_start_bracket = **ptr == '[';
     const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
+    const BOOL is_res = data->scheme_type == URL_SCHEME_RES;
     BOOL inside_brackets = has_start_bracket;
-    BOOL ignore_col = extras & IGNORE_PORT_DELIMITER;
+
+    /* res URIs don't have ports. */
+    BOOL ignore_col = (extras & IGNORE_PORT_DELIMITER) || is_res;
 
     /* We have to be careful with file schemes. */
     if(data->scheme_type == URL_SCHEME_FILE) {
@@ -1575,7 +1578,11 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWO
 
     data->host = *ptr;
 
-    while(!is_auth_delim(**ptr, known_scheme)) {
+    /* For res URIs, everything before the first '/' is
+     * considered the host.
+     */
+    while((!is_res && !is_auth_delim(**ptr, known_scheme)) ||
+          (is_res && **ptr && **ptr != '/')) {
         if(**ptr == ':' && !ignore_col) {
             /* We can ignore ':' if were inside brackets.*/
             if(!inside_brackets) {
@@ -1599,7 +1606,7 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWO
                     break;
                 }
             }
-        } else if(**ptr == '%' && known_scheme) {
+        } else if(**ptr == '%' && (known_scheme && !is_res)) {
             /* Has to be a legit % encoded value. */
             if(!check_pct_encoded(ptr)) {
                 *ptr = data->host;
@@ -1607,6 +1614,10 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWO
                 return FALSE;
             } else
                 continue;
+        } else if(is_res && is_forbidden_dos_path_char(**ptr)) {
+            *ptr = data->host;
+            data->host = NULL;
+            return FALSE;
         } else if(**ptr == ']')
             inside_brackets = FALSE;
         else if(**ptr == '[')
@@ -1631,7 +1642,7 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD flags, DWO
         data->host_len = *ptr - data->host;
 
     /* If the host is empty, then it's an unknown host type. */
-    if(data->host_len == 0)
+    if(data->host_len == 0 || is_res)
         data->host_type = Uri_HOST_UNKNOWN;
     else
         data->host_type = Uri_HOST_DNS;
@@ -2913,6 +2924,7 @@ static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
     const WCHAR *ptr;
     const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
     const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
+    const BOOL is_res = data->scheme_type == URL_SCHEME_RES;
 
     BOOL escape_pct = FALSE;
 
@@ -2961,7 +2973,7 @@ static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
     }
 
     for(; ptr < data->path+data->path_len; ++ptr) {
-        if(*ptr == '%') {
+        if(*ptr == '%' && !is_res) {
             const WCHAR *tmp = ptr;
             WCHAR val;
 
@@ -3004,7 +3016,7 @@ static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
                     uri->canon_uri[uri->canon_len] = '/';
                 ++uri->canon_len;
             }
-        } else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
+        } else if(known_scheme && !is_res && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
                   (!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) || is_file)) {
             if(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
                 /* Don't escape the character. */




More information about the wine-cvs mailing list