urlmon: Implemented canonicalization for reg-names.

This commit is contained in:
Thomas Mullaly 2010-07-10 15:12:27 -04:00 committed by Alexandre Julliard
parent ffe9f1aed0
commit 36d5856471
2 changed files with 160 additions and 51 deletions

View File

@ -99,7 +99,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE}, /* DOMAIN */
{"",S_FALSE,TRUE}, /* EXTENSION */
{"",S_FALSE,TRUE}, /* FRAGMENT */
{"www.winehq.org",S_OK,TRUE}, /* HOST */
{"www.winehq.org",S_OK,FALSE}, /* HOST */
{"",S_FALSE,FALSE}, /* PASSWORD */
{"/",S_OK,TRUE}, /* PATH */
{"/",S_OK,TRUE}, /* PATH_AND_QUERY */
@ -128,7 +128,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/tests",S_OK,TRUE},
{"/tests",S_OK,TRUE},
@ -157,7 +157,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/?query=x&return=y",S_OK,TRUE},
@ -186,7 +186,7 @@ static const uri_properties uri_tests[] = {
{"example.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"example.com",S_OK,TRUE},
{"example.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
{"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
@ -216,7 +216,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{".txt",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"ftp.winehq.org",S_OK,TRUE},
{"ftp.winehq.org",S_OK,FALSE},
{"wine",S_OK,FALSE},
{"/dir/foo%20bar.txt",S_OK,TRUE},
{"/dir/foo%20bar.txt",S_OK,TRUE},
@ -244,7 +244,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".mp3",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
{"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
@ -272,7 +272,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".txt",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"/tests/test%20file.README.txt",S_OK,TRUE},
{"/tests/test%20file.README.txt",S_OK,TRUE},
@ -300,7 +300,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"nothing:should:happen here",S_OK,TRUE},
{"nothing:should:happen here",S_OK,TRUE},
@ -445,7 +445,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -608,7 +608,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".mp3",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"/C:/test/test.mp3",S_OK,TRUE},
{"/C:/test/test.mp3",S_OK,TRUE},
@ -638,7 +638,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".mp3",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"server",S_OK,TRUE},
{"server",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/test.mp3",S_OK,TRUE},
{"/test.mp3",S_OK,TRUE},
@ -667,7 +667,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/test",S_OK,TRUE},
{"/test",S_OK,TRUE},
@ -697,7 +697,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/test",S_OK,TRUE},
{"/test",S_OK,TRUE},
@ -779,7 +779,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".ext",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"/../some dir/test.ext",S_OK,TRUE},
{"/../some dir/test.ext",S_OK,TRUE},
@ -807,7 +807,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_OK,TRUE},
{"",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"//implicit/wildcard/uri%20scheme",S_OK,TRUE},
{"//implicit/wildcard/uri%20scheme",S_OK,TRUE},
@ -837,7 +837,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{".com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE},
{"/.//google.com",S_OK,TRUE},
{"/.//google.com",S_OK,TRUE},
@ -868,7 +868,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"pass:word",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -899,7 +899,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"ftp.google.com",S_OK,TRUE},
{"ftp.google.com",S_OK,FALSE},
{"PASS",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -930,7 +930,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"ftp.google.com",S_OK,TRUE},
{"ftp.google.com",S_OK,FALSE},
{"PA%7B%7D",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -961,7 +961,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"ftp.google.com",S_OK,TRUE},
{"ftp.google.com",S_OK,FALSE},
{"",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -992,7 +992,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"ftp.google.com",S_OK,TRUE},
{"ftp.google.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1023,7 +1023,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"ftp.google.com",S_OK,TRUE},
{"ftp.google.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1053,7 +1053,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"word",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1085,7 +1085,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"%52%53ord",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1115,7 +1115,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"word",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1144,7 +1144,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"test",S_OK,TRUE},
{"test",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/?:word@winehq.org/",S_OK,TRUE},
@ -1173,7 +1173,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"#:word@winehq.org/",S_OK,TRUE},
{"test",S_OK,TRUE},
{"test",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1203,7 +1203,7 @@ static const uri_properties uri_tests[] = {
{"winehq.org",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"winehq.org",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"word",S_OK,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1353,7 +1353,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"4294967296",S_OK,TRUE},
{"4294967296",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1755,7 +1755,7 @@ static const uri_properties uri_tests[] = {
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"[v2.34]",S_OK,TRUE},
{"[v2.34]",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1785,7 +1785,7 @@ static const uri_properties uri_tests[] = {
{"[xyz:12345.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"[xyz:12345.com",S_OK,TRUE},
{"[xyz:12345.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/test",S_OK,TRUE},
{"/test",S_OK,TRUE},
@ -1847,7 +1847,7 @@ static const uri_properties uri_tests[] = {
{"[works].com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.[works].com",S_OK,TRUE},
{"www.[works].com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1877,7 +1877,7 @@ static const uri_properties uri_tests[] = {
{"google.com]",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.google.com]",S_OK,TRUE},
{"www.google.com]",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1907,7 +1907,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"w%XXw%GEw.google.com",S_OK,TRUE},
{"w%XXw%GEw.google.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1965,7 +1965,7 @@ static const uri_properties uri_tests[] = {
{"GOOGLE.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"GOOGLE.com",S_OK,TRUE},
{"GOOGLE.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -1995,7 +1995,7 @@ static const uri_properties uri_tests[] = {
{"google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.google.com",S_OK,TRUE},
{"www.google.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},
@ -2027,7 +2027,7 @@ static const uri_properties uri_tests[] = {
{"%7cgoogle%7c.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"www.%7cgoogle%7c.com",S_OK,TRUE},
{"www.%7cgoogle%7c.com",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,TRUE},
{"/",S_OK,TRUE},

View File

@ -1384,6 +1384,106 @@ static BOOL canonicalize_userinfo(const parse_data *data, Uri *uri, DWORD flags,
return TRUE;
}
/* Attempts to canonicalize a reg_name.
*
* Things that happen:
* 1) If Uri_CREATE_NO_CANONICALIZE flag is not set, then the reg_name is
* lower cased. Unless it's an unknown scheme type, which case it's
* no lower cased reguardless.
*
* 2) Unreserved % encoded characters are decoded for known
* scheme types.
*
* 3) Forbidden characters are % encoded as long as
* Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS flag is not set and
* it isn't an unknown scheme type.
*
* 4) If it's a file scheme and the host is "localhost" it's removed.
*/
static BOOL canonicalize_reg_name(const parse_data *data, Uri *uri,
DWORD flags, BOOL computeOnly) {
static const WCHAR localhostW[] =
{'l','o','c','a','l','h','o','s','t',0};
const WCHAR *ptr;
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
uri->host_start = uri->canon_len;
if(data->scheme_type == URL_SCHEME_FILE &&
data->host_len == lstrlenW(localhostW)) {
if(!StrCmpNIW(data->host, localhostW, data->host_len)) {
uri->host_start = -1;
uri->host_len = 0;
uri->host_type = Uri_HOST_UNKNOWN;
return TRUE;
}
}
for(ptr = data->host; ptr < data->host+data->host_len; ++ptr) {
if(*ptr == '%' && known_scheme) {
WCHAR val = decode_pct_val(ptr);
if(is_unreserved(val)) {
/* If NO_CANONICALZE is not set, then windows lower cases the
* decoded value.
*/
if(!(flags & Uri_CREATE_NO_CANONICALIZE) && isupperW(val)) {
if(!computeOnly)
uri->canon_uri[uri->canon_len] = tolowerW(val);
} else {
if(!computeOnly)
uri->canon_uri[uri->canon_len] = val;
}
++uri->canon_len;
/* Skip past the % encoded character. */
ptr += 2;
continue;
} else {
/* Just copy the % over. */
if(!computeOnly)
uri->canon_uri[uri->canon_len] = *ptr;
++uri->canon_len;
}
} else if(*ptr == '\\') {
/* Only unknown scheme types could have made it here with a '\\' in the host name. */
if(!computeOnly)
uri->canon_uri[uri->canon_len] = *ptr;
++uri->canon_len;
} else if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
!is_unreserved(*ptr) && !is_reserved(*ptr) && known_scheme) {
if(!computeOnly) {
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
/* The percent encoded value gets lower cased also. */
if(!(flags & Uri_CREATE_NO_CANONICALIZE)) {
uri->canon_uri[uri->canon_len+1] = tolowerW(uri->canon_uri[uri->canon_len+1]);
uri->canon_uri[uri->canon_len+2] = tolowerW(uri->canon_uri[uri->canon_len+2]);
}
}
uri->canon_len += 3;
} else {
if(!computeOnly) {
if(!(flags & Uri_CREATE_NO_CANONICALIZE) && known_scheme)
uri->canon_uri[uri->canon_len] = tolowerW(*ptr);
else
uri->canon_uri[uri->canon_len] = *ptr;
}
++uri->canon_len;
}
}
uri->host_len = uri->canon_len - uri->host_start;
if(!computeOnly)
TRACE("(%p %p %x %d): Canonicalize reg_name=%s len=%d\n", data, uri, flags,
computeOnly, debugstr_wn(uri->canon_uri+uri->host_start, uri->host_len),
uri->host_len);
return TRUE;
}
/* Attempts to canonicalize an implicit IPv4 address. */
static BOOL canonicalize_implicit_ipv4address(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
uri->host_start = uri->canon_len;
@ -1661,6 +1761,12 @@ static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOO
if(data->host) {
switch(data->host_type) {
case Uri_HOST_DNS:
uri->host_type = Uri_HOST_DNS;
if(!canonicalize_reg_name(data, uri, flags, computeOnly))
return FALSE;
break;
case Uri_HOST_IPV4:
uri->host_type = Uri_HOST_IPV4;
if(!canonicalize_ipv4address(data, uri, flags, computeOnly))
@ -1672,6 +1778,18 @@ static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOO
return FALSE;
uri->host_type = Uri_HOST_IPV6;
break;
case Uri_HOST_UNKNOWN:
if(data->host_len > 0 || data->scheme_type != URL_SCHEME_FILE) {
uri->host_start = uri->canon_len;
/* Nothing happens to unknown host types. */
if(!computeOnly)
memcpy(uri->canon_uri+uri->canon_len, data->host, data->host_len*sizeof(WCHAR));
uri->canon_len += data->host_len;
uri->host_len = data->host_len;
}
break;
default:
WARN("(%p %p %x %d): Canonicalization not supported yet\n", data,
@ -1720,9 +1838,11 @@ static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags,
/* TODO: Canonicalize the path of the URI. */
} else {
/* Opaque URI's don't have userinfo. */
/* Opaque URI's don't have an authority. */
uri->userinfo_start = uri->userinfo_split = -1;
uri->userinfo_len = 0;
uri->host_start = -1;
uri->host_len = 0;
}
return TRUE;
@ -1932,11 +2052,8 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
hres = S_OK;
} else {
/* Canonicalizing/parsing the host of a URI is only partially
* implemented, so return E_NOTIMPL for now.
*/
FIXME("(%p)->(%d %p %x) Partially implemented\n", This, uriProp, pbstrProperty, dwFlags);
return E_NOTIMPL;
*pbstrProperty = SysAllocStringLen(NULL, 0);
hres = S_FALSE;
}
if(!(*pbstrProperty))
@ -2041,14 +2158,6 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
switch(uriProp) {
case Uri_PROPERTY_HOST:
if(This->host_start == -1) {
/* Canonicalizing/parsing the host of a URI is only partially
* implemented, so return E_NOTIMPL for now.
*/
FIXME("(%p)->(%d %p %x) Partially implemented\n", This, uriProp, pcchProperty, dwFlags);
return E_NOTIMPL;
}
*pcchProperty = This->host_len;
/* '[' and ']' aren't included in the length. */