Module: wine Branch: master Commit: dffc9d312e78b6d7eb0e58e8b8062e5f695b0af3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=dffc9d312e78b6d7eb0e58e8b8...
Author: Thomas Mullaly thomas.mullaly@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. */