urlmon: Implemented case when relative URI has a path that doesn't start with '/'.
This commit is contained in:
parent
5d76d6b466
commit
290aca1b19
|
@ -5612,7 +5612,7 @@ typedef struct _uri_combine_test {
|
|||
static const uri_combine_test uri_combine_tests[] = {
|
||||
{ "http://google.com/fun/stuff",0,
|
||||
"../not/fun/stuff",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,TRUE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"http://google.com/not/fun/stuff",S_OK},
|
||||
{"google.com",S_OK},
|
||||
|
@ -5747,7 +5747,7 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
},
|
||||
{ "http://winehq.org/test/abc",0,
|
||||
"testing/abc/../test",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,TRUE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"http://winehq.org/test/testing/test",S_OK},
|
||||
{"winehq.org",S_OK},
|
||||
|
@ -5774,7 +5774,7 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
},
|
||||
{ "http://winehq.org/test/abc",0,
|
||||
"testing/abc/../test",Uri_CREATE_ALLOW_RELATIVE,
|
||||
URL_DONT_SIMPLIFY,S_OK,TRUE,
|
||||
URL_DONT_SIMPLIFY,S_OK,FALSE,
|
||||
{
|
||||
{"http://winehq.org:80/test/testing/abc/../test",S_OK},
|
||||
/* Default port is hidden in the authority. */
|
||||
|
@ -5802,7 +5802,7 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
},
|
||||
{ "http://winehq.org/test?query",0,
|
||||
"testing",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,TRUE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"http://winehq.org/testing",S_OK},
|
||||
{"winehq.org",S_OK},
|
||||
|
@ -5829,7 +5829,7 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
},
|
||||
{ "http://winehq.org/test#frag",0,
|
||||
"testing",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,TRUE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"http://winehq.org/testing",S_OK},
|
||||
{"winehq.org",S_OK},
|
||||
|
@ -5856,7 +5856,7 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
},
|
||||
{ "testing?query#frag",Uri_CREATE_ALLOW_RELATIVE,
|
||||
"test",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,TRUE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"test",S_OK},
|
||||
{"",S_FALSE},
|
||||
|
@ -6253,6 +6253,33 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
{URL_SCHEME_UNKNOWN,S_OK},
|
||||
{URLZONE_INVALID,E_NOTIMPL}
|
||||
}
|
||||
},
|
||||
{ "file:///c:/",0,
|
||||
"../testing/test",Uri_CREATE_ALLOW_RELATIVE,
|
||||
0,S_OK,FALSE,
|
||||
{
|
||||
{"file:///c:/testing/test",S_OK},
|
||||
{"",S_FALSE},
|
||||
{"file:///c:/testing/test",S_OK},
|
||||
{"",S_FALSE},
|
||||
{"",S_FALSE},
|
||||
{"",S_FALSE},
|
||||
{"",S_FALSE},
|
||||
{"",S_FALSE},
|
||||
{"/c:/testing/test",S_OK},
|
||||
{"/c:/testing/test",S_OK},
|
||||
{"",S_FALSE},
|
||||
{"file:///c:/testing/test",S_OK},
|
||||
{"file",S_OK},
|
||||
{"",S_FALSE},
|
||||
{"",S_FALSE}
|
||||
},
|
||||
{
|
||||
{Uri_HOST_UNKNOWN,S_OK},
|
||||
{0,S_FALSE},
|
||||
{URL_SCHEME_FILE,S_OK},
|
||||
{URLZONE_INVALID,E_NOTIMPL}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5679,6 +5679,51 @@ HRESULT WINAPI CreateIUriBuilder(IUri *pIUri, DWORD dwFlags, DWORD_PTR dwReserve
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* Merges the base path with the relative path and stores the resulting path
|
||||
* and path len in 'result' and 'result_len'.
|
||||
*/
|
||||
static HRESULT merge_paths(parse_data *data, const WCHAR *base, DWORD base_len, const WCHAR *relative,
|
||||
DWORD relative_len, WCHAR **result, DWORD *result_len, DWORD flags)
|
||||
{
|
||||
const WCHAR *end = NULL;
|
||||
DWORD base_copy_len = 0;
|
||||
WCHAR *ptr;
|
||||
|
||||
if(base_len) {
|
||||
/* Find the characters the will be copied over from
|
||||
* the base path.
|
||||
*/
|
||||
end = str_last_of(base, base+(base_len-1), '/');
|
||||
if(!end && data->scheme_type == URL_SCHEME_FILE)
|
||||
/* Try looking for a '\\'. */
|
||||
end = str_last_of(base, base+(base_len-1), '\\');
|
||||
}
|
||||
|
||||
if(end) {
|
||||
base_copy_len = (end+1)-base;
|
||||
*result = heap_alloc((base_copy_len+relative_len+1)*sizeof(WCHAR));
|
||||
} else
|
||||
*result = heap_alloc((relative_len+1)*sizeof(WCHAR));
|
||||
|
||||
if(!(*result)) {
|
||||
*result_len = 0;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ptr = *result;
|
||||
if(end) {
|
||||
memcpy(ptr, base, base_copy_len*sizeof(WCHAR));
|
||||
ptr += base_copy_len;
|
||||
}
|
||||
|
||||
memcpy(ptr, relative, relative_len*sizeof(WCHAR));
|
||||
ptr += relative_len;
|
||||
*ptr = '\0';
|
||||
|
||||
*result_len = (ptr-*result);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result) {
|
||||
Uri *ret;
|
||||
HRESULT hr;
|
||||
|
@ -5777,10 +5822,16 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result)
|
|||
data.query_len = base->query_len;
|
||||
}
|
||||
} else {
|
||||
const WCHAR *ptr, **pptr;
|
||||
DWORD path_offset = 0, path_len = 0;
|
||||
|
||||
/* There's two possibilities on what will happen to the path component
|
||||
* of the result IUri. First, if the relative path begins with a '/'
|
||||
* then the resulting path will just be the relative path. Second, if
|
||||
* relative path doesn't begin with a '/' then the base path and relative
|
||||
* path are merged together.
|
||||
*/
|
||||
if(relative->path_len && *(relative->canon_uri+relative->path_start) == '/') {
|
||||
const WCHAR *ptr, **pptr;
|
||||
WCHAR *tmp = NULL;
|
||||
BOOL copy_drive_path = FALSE;
|
||||
|
||||
|
@ -5815,19 +5866,25 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result)
|
|||
|
||||
memcpy(tmp, relative->canon_uri+relative->path_start, relative->path_len*sizeof(WCHAR));
|
||||
path[path_len] = '\0';
|
||||
|
||||
ptr = path;
|
||||
pptr = &ptr;
|
||||
if((data.is_opaque && !parse_path_opaque(pptr, &data, 0)) ||
|
||||
(!data.is_opaque && !parse_path_hierarchical(pptr, &data, 0))) {
|
||||
heap_free(path);
|
||||
*result = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
} else {
|
||||
FIXME("Path merging not implemented yet!\n");
|
||||
/* Merge the base path with the relative path. */
|
||||
hr = merge_paths(&data, base->canon_uri+base->path_start, base->path_len,
|
||||
relative->canon_uri+relative->path_start, relative->path_len,
|
||||
&path, &path_len, flags);
|
||||
if(FAILED(hr)) {
|
||||
*result = NULL;
|
||||
return E_NOTIMPL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* If the resulting IUri is a file URI, the drive path isn't
|
||||
* reduced out when the dot segments are removed.
|
||||
*/
|
||||
if(path_len >= 3 && data.scheme_type == URL_SCHEME_FILE && !data.host) {
|
||||
if(*path == '/' && is_drive_path(path+1))
|
||||
path_offset = 2;
|
||||
else if(is_drive_path(path))
|
||||
path_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the dot segments need to be removed from the path. */
|
||||
|
@ -5836,19 +5893,28 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result)
|
|||
DWORD new_len = remove_dot_segments(path+offset,path_len-offset);
|
||||
|
||||
if(new_len != path_len) {
|
||||
WCHAR *tmp = heap_realloc(path, (new_len+1)*sizeof(WCHAR));
|
||||
WCHAR *tmp = heap_realloc(path, (path_offset+new_len+1)*sizeof(WCHAR));
|
||||
if(!tmp) {
|
||||
heap_free(path);
|
||||
*result = NULL;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
tmp[new_len] = '\0';
|
||||
data.path = tmp;
|
||||
data.path_len = new_len;
|
||||
tmp[new_len+offset] = '\0';
|
||||
path = tmp;
|
||||
path_len = new_len+offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the path component is valid. */
|
||||
ptr = path;
|
||||
pptr = &ptr;
|
||||
if((data.is_opaque && !parse_path_opaque(pptr, &data, 0)) ||
|
||||
(!data.is_opaque && !parse_path_hierarchical(pptr, &data, 0))) {
|
||||
heap_free(path);
|
||||
*result = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
if(relative->fragment_start > -1) {
|
||||
|
|
Loading…
Reference in New Issue