Commit 87bdf4ed authored by Thomas Mullaly's avatar Thomas Mullaly Committed by Alexandre Julliard

urlmon: Implemented case when the relative URI doesn't have a path component in…

urlmon: Implemented case when the relative URI doesn't have a path component in CoInternetCombineIUri.
parent 7c6bb2fb
...@@ -5634,7 +5634,7 @@ static const uri_combine_test uri_combine_tests[] = { ...@@ -5634,7 +5634,7 @@ static const uri_combine_test uri_combine_tests[] = {
}, },
{ "http://google.com/use/base/path",0, { "http://google.com/use/base/path",0,
"?relative",Uri_CREATE_ALLOW_RELATIVE, "?relative",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,TRUE, 0,S_OK,FALSE,
{ {
{"http://google.com/use/base/path?relative",S_OK}, {"http://google.com/use/base/path?relative",S_OK},
{"google.com",S_OK}, {"google.com",S_OK},
...@@ -6026,7 +6026,7 @@ static const uri_combine_test uri_combine_tests[] = { ...@@ -6026,7 +6026,7 @@ static const uri_combine_test uri_combine_tests[] = {
/* Windows doesn't validate the query from the relative Uri. */ /* Windows doesn't validate the query from the relative Uri. */
{ "http://google.com/test",0, { "http://google.com/test",0,
"?Tes%XXt",Uri_CREATE_ALLOW_RELATIVE, "?Tes%XXt",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,TRUE, 0,S_OK,FALSE,
{ {
{"http://google.com/test?Tes%XXt",S_OK}, {"http://google.com/test?Tes%XXt",S_OK},
{"google.com",S_OK}, {"google.com",S_OK},
...@@ -6054,7 +6054,7 @@ static const uri_combine_test uri_combine_tests[] = { ...@@ -6054,7 +6054,7 @@ static const uri_combine_test uri_combine_tests[] = {
/* Windows doesn't validate the fragment from the relative Uri. */ /* Windows doesn't validate the fragment from the relative Uri. */
{ "http://google.com/test",0, { "http://google.com/test",0,
"#Tes%XXt",Uri_CREATE_ALLOW_RELATIVE, "#Tes%XXt",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,TRUE, 0,S_OK,FALSE,
{ {
{"http://google.com/test#Tes%XXt",S_OK}, {"http://google.com/test#Tes%XXt",S_OK},
{"google.com",S_OK}, {"google.com",S_OK},
...@@ -6134,6 +6134,92 @@ static const uri_combine_test uri_combine_tests[] = { ...@@ -6134,6 +6134,92 @@ static const uri_combine_test uri_combine_tests[] = {
{URL_SCHEME_FILE,S_OK}, {URL_SCHEME_FILE,S_OK},
{URLZONE_INVALID,E_NOTIMPL} {URLZONE_INVALID,E_NOTIMPL}
} }
},
/* A '/' is added if the base URI doesn't have a path and the
* relative URI doesn't contain a path (since the base URI is
* hierarchical.
*/
{ "http://google.com",Uri_CREATE_NO_CANONICALIZE,
"?test",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,FALSE,
{
{"http://google.com/?test",S_OK},
{"google.com",S_OK},
{"http://google.com/?test",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"",S_FALSE},
{"google.com",S_OK},
{"",S_FALSE},
{"/",S_OK},
{"/?test",S_OK},
{"?test",S_OK},
{"http://google.com/?test",S_OK},
{"http",S_OK},
{"",S_FALSE},
{"",S_FALSE}
},
{
{Uri_HOST_DNS,S_OK},
{80,S_OK},
{URL_SCHEME_HTTP,S_OK},
{URLZONE_INVALID,E_NOTIMPL}
}
},
{ "zip://google.com",Uri_CREATE_NO_CANONICALIZE,
"?test",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,FALSE,
{
{"zip://google.com/?test",S_OK},
{"google.com",S_OK},
{"zip://google.com/?test",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"",S_FALSE},
{"google.com",S_OK},
{"",S_FALSE},
{"/",S_OK},
{"/?test",S_OK},
{"?test",S_OK},
{"zip://google.com/?test",S_OK},
{"zip",S_OK},
{"",S_FALSE},
{"",S_FALSE}
},
{
{Uri_HOST_DNS,S_OK},
{0,S_FALSE},
{URL_SCHEME_UNKNOWN,S_OK},
{URLZONE_INVALID,E_NOTIMPL}
}
},
/* No path is appended since the base URI is opaque. */
{ "zip:?testing",0,
"?test",Uri_CREATE_ALLOW_RELATIVE,
0,S_OK,FALSE,
{
{"zip:?test",S_OK},
{"",S_FALSE},
{"zip:?test",S_OK},
{"",S_FALSE},
{"",S_FALSE},
{"",S_FALSE},
{"",S_FALSE},
{"",S_FALSE},
{"",S_OK},
{"?test",S_OK},
{"?test",S_OK},
{"zip:?test",S_OK},
{"zip",S_OK},
{"",S_FALSE},
{"",S_FALSE}
},
{
{Uri_HOST_UNKNOWN,S_OK},
{0,S_FALSE},
{URL_SCHEME_UNKNOWN,S_OK},
{URLZONE_INVALID,E_NOTIMPL}
}
} }
}; };
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define SKIP_IP_FUTURE_CHECK 0x10 #define SKIP_IP_FUTURE_CHECK 0x10
#define IGNORE_PORT_DELIMITER 0x20 #define IGNORE_PORT_DELIMITER 0x20
#define RAW_URI_FORCE_PORT_DISP 0x1
WINE_DEFAULT_DEBUG_CHANNEL(urlmon); WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
static const IID IID_IUriObj = {0x4b364760,0x9f51,0x11df,{0x98,0x1c,0x08,0x00,0x20,0x0c,0x9a,0x66}}; static const IID IID_IUriObj = {0x4b364760,0x9f51,0x11df,{0x98,0x1c,0x08,0x00,0x20,0x0c,0x9a,0x66}};
...@@ -3916,7 +3918,7 @@ static HRESULT validate_components(const UriBuilder *builder, parse_data *data, ...@@ -3916,7 +3918,7 @@ static HRESULT validate_components(const UriBuilder *builder, parse_data *data,
} }
/* Generates a raw uri string using the parse_data. */ /* Generates a raw uri string using the parse_data. */
static DWORD generate_raw_uri(const parse_data *data, BSTR uri) { static DWORD generate_raw_uri(const parse_data *data, BSTR uri, DWORD flags) {
DWORD length = 0; DWORD length = 0;
if(data->scheme) { if(data->scheme) {
...@@ -3991,7 +3993,7 @@ static DWORD generate_raw_uri(const parse_data *data, BSTR uri) { ...@@ -3991,7 +3993,7 @@ static DWORD generate_raw_uri(const parse_data *data, BSTR uri) {
is_default = TRUE; is_default = TRUE;
} }
if(!is_default) { if(!is_default || flags & RAW_URI_FORCE_PORT_DISP) {
if(uri) if(uri)
uri[length] = ':'; uri[length] = ':';
++length; ++length;
...@@ -4038,12 +4040,12 @@ static DWORD generate_raw_uri(const parse_data *data, BSTR uri) { ...@@ -4038,12 +4040,12 @@ static DWORD generate_raw_uri(const parse_data *data, BSTR uri) {
static HRESULT generate_uri(const UriBuilder *builder, const parse_data *data, Uri *uri, DWORD flags) { static HRESULT generate_uri(const UriBuilder *builder, const parse_data *data, Uri *uri, DWORD flags) {
HRESULT hr; HRESULT hr;
DWORD length = generate_raw_uri(data, NULL); DWORD length = generate_raw_uri(data, NULL, 0);
uri->raw_uri = SysAllocStringLen(NULL, length); uri->raw_uri = SysAllocStringLen(NULL, length);
if(!uri->raw_uri) if(!uri->raw_uri)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
generate_raw_uri(data, uri->raw_uri); generate_raw_uri(data, uri->raw_uri, 0);
hr = canonicalize_uri(data, uri, flags); hr = canonicalize_uri(data, uri, flags);
if(FAILED(hr)) { if(FAILED(hr)) {
...@@ -5605,16 +5607,15 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result) ...@@ -5605,16 +5607,15 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result)
Uri *ret; Uri *ret;
HRESULT hr; HRESULT hr;
parse_data data; parse_data data;
DWORD create_flags = 0, len = 0;
memset(&data, 0, sizeof(parse_data));
/* Base case is when the relative Uri has a scheme name, /* Base case is when the relative Uri has a scheme name,
* if it does, then 'result' will contain the same data * if it does, then 'result' will contain the same data
* as the relative Uri. * as the relative Uri.
*/ */
if(relative->scheme_start > -1) { if(relative->scheme_start > -1) {
DWORD create_flags = 0;
memset(&data, 0, sizeof(parse_data));
data.uri = SysAllocString(relative->raw_uri); data.uri = SysAllocString(relative->raw_uri);
if(!data.uri) { if(!data.uri) {
*result = NULL; *result = NULL;
...@@ -5642,8 +5643,103 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result) ...@@ -5642,8 +5643,103 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result)
*result = URI(ret); *result = URI(ret);
} else { } else {
*result = NULL; DWORD raw_flags = 0;
return E_NOTIMPL;
if(base->scheme_start > -1) {
data.scheme = base->canon_uri+base->scheme_start;
data.scheme_len = base->scheme_len;
data.scheme_type = base->scheme_type;
} else {
data.is_relative = TRUE;
data.scheme_type = URL_SCHEME_UNKNOWN;
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(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(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(base->has_port) {
data.has_port = TRUE;
data.port_value = base->port;
}
} else
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) {
/* Just set the path as a '/' if the base didn't have
* one and if it's an hierarchical URI.
*/
static const WCHAR slashW[] = {'/',0};
data.path = slashW;
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;
}
} else {
FIXME("Path merging not implemented yet!\n");
*result = NULL;
return E_NOTIMPL;
}
if(relative->fragment_start > -1) {
data.fragment = relative->canon_uri+relative->fragment_start;
data.fragment_len = relative->fragment_len;
}
if(flags & URL_DONT_SIMPLIFY)
raw_flags |= RAW_URI_FORCE_PORT_DISP;
len = generate_raw_uri(&data, data.uri, raw_flags);
data.uri = SysAllocStringLen(NULL, len);
if(!data.uri) {
*result = NULL;
return E_OUTOFMEMORY;
}
generate_raw_uri(&data, data.uri, raw_flags);
ret = create_uri_obj();
if(!ret) {
SysFreeString(data.uri);
*result = NULL;
return E_OUTOFMEMORY;
}
ret->raw_uri = data.uri;
hr = canonicalize_uri(&data, ret, create_flags);
if(FAILED(hr)) {
IUri_Release(URI(ret));
*result = NULL;
return hr;
}
apply_default_flags(&create_flags);
ret->create_flags = create_flags;
*result = URI(ret);
} }
return S_OK; return S_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment