diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c index 9d9487a6a7b..4b0e7885f0c 100644 --- a/dlls/urlmon/tests/uri.c +++ b/dlls/urlmon/tests/uri.c @@ -121,6 +121,7 @@ typedef struct _uri_dword_property { DWORD value; HRESULT expected; BOOL todo; + BOOL broken_combine_hres; } uri_dword_property; typedef struct _uri_properties { @@ -6693,6 +6694,60 @@ static const uri_combine_test uri_combine_tests[] = { {URL_SCHEME_MK,S_OK}, {URLZONE_INVALID,E_NOTIMPL} } + }, + { "http://winehq.org/dir/test?querystring",0, + "//winehq.com/#hash",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"http://winehq.com/#hash",S_OK}, + {"winehq.com",S_OK}, + {"http://winehq.com/#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"/",S_OK}, + {"/",S_OK}, + {"",S_FALSE}, + {"http://winehq.com/#hash",S_OK}, + {"http",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_DNS,S_OK}, + {80,S_OK,FALSE,TRUE}, + {URL_SCHEME_HTTP,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "http://winehq.org/dir/test?querystring",0, + "//winehq.com/dir2/../dir/file.txt?query#hash",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"winehq.com",S_OK}, + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"winehq.com",S_OK}, + {".txt",S_OK}, + {"#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"/dir/file.txt",S_OK}, + {"/dir/file.txt?query",S_OK}, + {"?query",S_OK}, + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"http",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_DNS,S_OK}, + {80,S_OK,FALSE,TRUE}, + {URL_SCHEME_HTTP,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } } }; @@ -10035,11 +10090,12 @@ static void test_CoInternetCombineIUri(void) { prop.value, received, i, j); } } else { - ok(hr == prop.expected, + ok(hr == prop.expected || broken(prop.broken_combine_hres && hr == S_FALSE), "Error: IUri_GetPropertyDWORD returned 0x%08x, expected 0x%08x on uri_combine_tests[%d].dword_props[%d].\n", hr, prop.expected, i, j); - ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", - prop.value, received, i, j); + if(!prop.broken_combine_hres || hr != S_FALSE) + ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", + prop.value, received, i, j); } } } @@ -10351,11 +10407,12 @@ static void test_CoInternetCombineUrlEx(void) { prop.value, received, i, j); } } else { - ok(hr == prop.expected, + ok(hr == prop.expected || broken(prop.broken_combine_hres && hr == S_FALSE), "Error: IUri_GetPropertyDWORD returned 0x%08x, expected 0x%08x on uri_combine_tests[%d].dword_props[%d].\n", hr, prop.expected, i, j); - ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", - prop.value, received, i, j); + if(!prop.broken_combine_hres || hr != S_FALSE) + ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", + prop.value, received, i, j); } } } diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c index 653e22cdf96..2710c7c064f 100644 --- a/dlls/urlmon/uri.c +++ b/dlls/urlmon/uri.c @@ -6427,6 +6427,7 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result, Uri *ret; HRESULT hr; parse_data data; + Uri *proc_uri = base; DWORD create_flags = 0, len = 0; memset(&data, 0, sizeof(parse_data)); @@ -6483,35 +6484,38 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result, create_flags |= Uri_CREATE_ALLOW_RELATIVE; } - if(base->authority_start > -1) { - if(base->userinfo_start > -1 && base->userinfo_split != 0) { - data.username = base->canon_uri+base->userinfo_start; - data.username_len = (base->userinfo_split > -1) ? base->userinfo_split : base->userinfo_len; + if(relative->authority_start > -1) + proc_uri = relative; + + if(proc_uri->authority_start > -1) { + if(proc_uri->userinfo_start > -1 && proc_uri->userinfo_split != 0) { + data.username = proc_uri->canon_uri+proc_uri->userinfo_start; + data.username_len = (proc_uri->userinfo_split > -1) ? proc_uri->userinfo_split : proc_uri->userinfo_len; } - if(base->userinfo_split > -1) { - data.password = base->canon_uri+base->userinfo_start+base->userinfo_split+1; - data.password_len = base->userinfo_len-base->userinfo_split-1; + if(proc_uri->userinfo_split > -1) { + data.password = proc_uri->canon_uri+proc_uri->userinfo_start+proc_uri->userinfo_split+1; + data.password_len = proc_uri->userinfo_len-proc_uri->userinfo_split-1; } - if(base->host_start > -1) { - data.host = base->canon_uri+base->host_start; - data.host_len = base->host_len; - data.host_type = base->host_type; + if(proc_uri->host_start > -1) { + data.host = proc_uri->canon_uri+proc_uri->host_start; + data.host_len = proc_uri->host_len; + data.host_type = proc_uri->host_type; } - if(base->has_port) { + if(proc_uri->has_port) { data.has_port = TRUE; - data.port_value = base->port; + data.port_value = proc_uri->port; } } else if(base->scheme_type != URL_SCHEME_FILE) data.is_opaque = TRUE; - if(relative->path_start == -1 || !relative->path_len) { - if(base->path_start > -1) { - data.path = base->canon_uri+base->path_start; - data.path_len = base->path_len; - } else if((base->path_start == -1 || !base->path_len) && !data.is_opaque) { + if(proc_uri == relative || relative->path_start == -1 || !relative->path_len) { + if(proc_uri->path_start > -1) { + data.path = proc_uri->canon_uri+proc_uri->path_start; + data.path_len = proc_uri->path_len; + } else if(!data.is_opaque) { /* Just set the path as a '/' if the base didn't have * one and if it's an hierarchical URI. */ @@ -6520,12 +6524,12 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result, data.path_len = 1; } - if(relative->query_start > -1) { - data.query = relative->canon_uri+relative->query_start; - data.query_len = relative->query_len; - } else if(base->query_start > -1) { - data.query = base->canon_uri+base->query_start; - data.query_len = base->query_len; + if(relative->query_start > -1) + proc_uri = relative; + + if(proc_uri->query_start > -1) { + data.query = proc_uri->canon_uri+proc_uri->query_start; + data.query_len = proc_uri->query_len; } } else { const WCHAR *ptr, **pptr;