urlmon: Added implementation for PARSE_CANONICALIZE in CoInternetParseIUri.
This commit is contained in:
parent
4e07082eda
commit
8cf81d912f
|
@ -30,6 +30,7 @@
|
|||
#include "urlmon.h"
|
||||
#include "shlwapi.h"
|
||||
#include "wininet.h"
|
||||
#include "strsafe.h"
|
||||
|
||||
#define URI_STR_PROPERTY_COUNT Uri_PROPERTY_STRING_LAST+1
|
||||
#define URI_DWORD_PROPERTY_COUNT (Uri_PROPERTY_DWORD_LAST - Uri_PROPERTY_DWORD_START)+1
|
||||
|
@ -5897,6 +5898,32 @@ static const uri_combine_test uri_combine_tests[] = {
|
|||
}
|
||||
};
|
||||
|
||||
typedef struct _uri_parse_test {
|
||||
const char *uri;
|
||||
DWORD uri_flags;
|
||||
PARSEACTION action;
|
||||
DWORD flags;
|
||||
const char *property;
|
||||
HRESULT expected;
|
||||
BOOL todo;
|
||||
} uri_parse_test;
|
||||
|
||||
static const uri_parse_test uri_parse_tests[] = {
|
||||
/* PARSE_CANONICALIZE tests. */
|
||||
{"zip://google.com/test<|>",0,PARSE_CANONICALIZE,0,"zip://google.com/test<|>",S_OK,FALSE},
|
||||
{"http://google.com/test<|>",0,PARSE_CANONICALIZE,0,"http://google.com/test%3C%7C%3E",S_OK,FALSE},
|
||||
{"http://google.com/%30%23%3F",0,PARSE_CANONICALIZE,URL_UNESCAPE,"http://google.com/0#?",S_OK,FALSE},
|
||||
{"test <|>",Uri_CREATE_ALLOW_RELATIVE,PARSE_CANONICALIZE,URL_ESCAPE_UNSAFE,"test %3C%7C%3E",S_OK,FALSE},
|
||||
{"test <|>",Uri_CREATE_ALLOW_RELATIVE,PARSE_CANONICALIZE,URL_ESCAPE_SPACES_ONLY,"test%20<|>",S_OK,FALSE},
|
||||
{"test%20<|>",Uri_CREATE_ALLOW_RELATIVE,PARSE_CANONICALIZE,URL_UNESCAPE|URL_ESCAPE_UNSAFE,"test%20%3C%7C%3E",S_OK,FALSE},
|
||||
{"http://google.com/%20",0,PARSE_CANONICALIZE,URL_ESCAPE_PERCENT,"http://google.com/%2520",S_OK,FALSE},
|
||||
{"http://google.com/test/../",Uri_CREATE_NO_CANONICALIZE,PARSE_CANONICALIZE,URL_DONT_SIMPLIFY,"http://google.com/test/../",S_OK,FALSE},
|
||||
{"http://google.com/test/../",Uri_CREATE_NO_CANONICALIZE,PARSE_CANONICALIZE,URL_NO_META,"http://google.com/test/../",S_OK,FALSE},
|
||||
{"http://google.com/test/../",Uri_CREATE_NO_CANONICALIZE,PARSE_CANONICALIZE,0,"http://google.com/",S_OK,FALSE},
|
||||
{"zip://google.com/test/../",Uri_CREATE_NO_CANONICALIZE,PARSE_CANONICALIZE,0,"zip://google.com/",S_OK,FALSE},
|
||||
{"file:///c:/test/../test",Uri_CREATE_NO_CANONICALIZE,PARSE_CANONICALIZE,URL_DONT_SIMPLIFY,"file:///c:/test/../test",S_OK,FALSE}
|
||||
};
|
||||
|
||||
static inline LPWSTR a2w(LPCSTR str) {
|
||||
LPWSTR ret = NULL;
|
||||
|
||||
|
@ -9456,6 +9483,8 @@ static void test_CoInternetParseIUri_InvalidArgs(void) {
|
|||
hr = pCreateUri(http_urlW, 0, 0, &uri);
|
||||
ok(SUCCEEDED(hr), "Error: CreateUri returned 0x%08x.\n", hr);
|
||||
if(SUCCEEDED(hr)) {
|
||||
DWORD expected_len;
|
||||
|
||||
result = -1;
|
||||
hr = pCoInternetParseIUri(uri, PARSE_CANONICALIZE, 0, NULL, 0, &result, 0);
|
||||
ok(hr == E_INVALIDARG, "Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x.\n",
|
||||
|
@ -9489,10 +9518,66 @@ static void test_CoInternetParseIUri_InvalidArgs(void) {
|
|||
ok(hr == E_FAIL, "Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x.\n",
|
||||
hr, E_FAIL);
|
||||
ok(!result, "Error: Expected 'result' to be 0, but was %d.\n", result);
|
||||
|
||||
expected_len = lstrlenW(http_urlW);
|
||||
result = -1;
|
||||
hr = pCoInternetParseIUri(uri, PARSE_CANONICALIZE, 0, tmp, 3, &result, 0);
|
||||
ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER,
|
||||
"Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x.\n",
|
||||
hr, STRSAFE_E_INSUFFICIENT_BUFFER);
|
||||
ok(result == expected_len, "Error: Expected 'result' to be %d, but was %d instead.\n",
|
||||
expected_len, result);
|
||||
}
|
||||
if(uri) IUri_Release(uri);
|
||||
}
|
||||
|
||||
static void test_CoInternetParseIUri(void) {
|
||||
DWORD i;
|
||||
|
||||
for(i = 0; i < sizeof(uri_parse_tests)/sizeof(uri_parse_tests[0]); ++i) {
|
||||
HRESULT hr;
|
||||
IUri *uri;
|
||||
LPWSTR uriW;
|
||||
uri_parse_test test = uri_parse_tests[i];
|
||||
|
||||
uriW = a2w(test.uri);
|
||||
hr = pCreateUri(uriW, test.uri_flags, 0, &uri);
|
||||
ok(SUCCEEDED(hr), "Error: CreateUri returned 0x%08x on uri_parse_tests[%d].\n", hr, i);
|
||||
if(SUCCEEDED(hr)) {
|
||||
WCHAR result[INTERNET_MAX_URL_LENGTH+1];
|
||||
DWORD result_len = -1;
|
||||
|
||||
hr = pCoInternetParseIUri(uri, test.action, test.flags, result, INTERNET_MAX_URL_LENGTH+1, &result_len, 0);
|
||||
if(test.todo) {
|
||||
todo_wine {
|
||||
ok(hr == test.expected,
|
||||
"Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x on uri_parse_tests[%d].\n",
|
||||
hr, test.expected, i);
|
||||
}
|
||||
} else {
|
||||
ok(hr == test.expected,
|
||||
"Error: CoInternetParseIUri returned 0x%08x, expected 0x%08x on uri_parse_tests[%d].\n",
|
||||
hr, test.expected, i);
|
||||
}
|
||||
if(SUCCEEDED(hr)) {
|
||||
DWORD len = lstrlenA(test.property);
|
||||
ok(!strcmp_aw(test.property, result),
|
||||
"Error: Expected %s but got %s instead on uri_parse_tests[%d].\n",
|
||||
test.property, wine_dbgstr_w(result), i);
|
||||
ok(len == result_len,
|
||||
"Error: Expected %d, but got %d instead on uri_parse_tests[%d].\n",
|
||||
len, result_len, i);
|
||||
} else {
|
||||
ok(!result_len,
|
||||
"Error: Expected 'result_len' to be 0, but was %d on uri_parse_tests[%d].\n",
|
||||
result_len, i);
|
||||
}
|
||||
}
|
||||
if(uri) IUri_Release(uri);
|
||||
heap_free(uriW);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(uri) {
|
||||
HMODULE hurlmon;
|
||||
|
||||
|
@ -9585,6 +9670,9 @@ START_TEST(uri) {
|
|||
trace("test CoInternetParseIUri Invalid Args...\n");
|
||||
test_CoInternetParseIUri_InvalidArgs();
|
||||
|
||||
trace("test CoInternetParseIUri...\n");
|
||||
test_CoInternetParseIUri();
|
||||
|
||||
register_protocols();
|
||||
|
||||
trace("test CoInternetCombineIUri pluggable...\n");
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#define NO_SHLWAPI_REG
|
||||
#include "shlwapi.h"
|
||||
|
||||
#include "strsafe.h"
|
||||
|
||||
#define UINT_MAX 0xffffffff
|
||||
#define USHORT_MAX 0xffff
|
||||
|
||||
|
@ -6081,6 +6083,109 @@ HRESULT WINAPI CoInternetCombineUrlEx(IUri *pBaseUri, LPCWSTR pwzRelativeUrl, DW
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT parse_canonicalize(const Uri *uri, DWORD flags, LPWSTR output,
|
||||
DWORD output_len, DWORD *result_len)
|
||||
{
|
||||
const WCHAR *ptr = NULL;
|
||||
WCHAR *path = NULL;
|
||||
const WCHAR **pptr;
|
||||
WCHAR buffer[INTERNET_MAX_URL_LENGTH+1];
|
||||
DWORD len = 0;
|
||||
BOOL reduce_path;
|
||||
|
||||
/* URL_UNESCAPE only has effect if none of the URL_ESCAPE flags are set. */
|
||||
const BOOL allow_unescape = !(flags & URL_ESCAPE_UNSAFE) &&
|
||||
!(flags & URL_ESCAPE_SPACES_ONLY) &&
|
||||
!(flags & URL_ESCAPE_PERCENT);
|
||||
|
||||
/* Check if the dot segments need to be removed from the
|
||||
* path component.
|
||||
*/
|
||||
if(uri->scheme_start > -1 && uri->path_start > -1) {
|
||||
ptr = uri->canon_uri+uri->scheme_start+uri->scheme_len+1;
|
||||
pptr = &ptr;
|
||||
}
|
||||
reduce_path = !(flags & URL_NO_META) &&
|
||||
!(flags & URL_DONT_SIMPLIFY) &&
|
||||
ptr && check_hierarchical(pptr);
|
||||
|
||||
for(ptr = uri->canon_uri; ptr < uri->canon_uri+uri->canon_len; ++ptr) {
|
||||
BOOL do_default_action = TRUE;
|
||||
|
||||
/* Keep track of the path if we need to remove dot segments from
|
||||
* it later.
|
||||
*/
|
||||
if(reduce_path && !path && ptr == uri->canon_uri+uri->path_start)
|
||||
path = buffer+len;
|
||||
|
||||
/* Check if it's time to reduce the path. */
|
||||
if(reduce_path && ptr == uri->canon_uri+uri->path_start+uri->path_len) {
|
||||
DWORD current_path_len = (buffer+len) - path;
|
||||
DWORD new_path_len = remove_dot_segments(path, current_path_len);
|
||||
|
||||
/* Update the current length. */
|
||||
len -= (current_path_len-new_path_len);
|
||||
reduce_path = FALSE;
|
||||
}
|
||||
|
||||
if(*ptr == '%') {
|
||||
const WCHAR decoded = decode_pct_val(ptr);
|
||||
if(decoded) {
|
||||
if(allow_unescape && (flags & URL_UNESCAPE)) {
|
||||
buffer[len++] = decoded;
|
||||
ptr += 2;
|
||||
do_default_action = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* See if %'s needed to encoded. */
|
||||
if(do_default_action && (flags & URL_ESCAPE_PERCENT)) {
|
||||
pct_encode_val(*ptr, buffer+len);
|
||||
len += 3;
|
||||
do_default_action = FALSE;
|
||||
}
|
||||
} else if(*ptr == ' ') {
|
||||
if((flags & URL_ESCAPE_SPACES_ONLY) &&
|
||||
!(flags & URL_ESCAPE_UNSAFE)) {
|
||||
pct_encode_val(*ptr, buffer+len);
|
||||
len += 3;
|
||||
do_default_action = FALSE;
|
||||
}
|
||||
} else if(!is_reserved(*ptr) && !is_unreserved(*ptr)) {
|
||||
if(flags & URL_ESCAPE_UNSAFE) {
|
||||
pct_encode_val(*ptr, buffer+len);
|
||||
len += 3;
|
||||
do_default_action = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(do_default_action)
|
||||
buffer[len++] = *ptr;
|
||||
}
|
||||
|
||||
/* Sometimes the path is the very last component of the IUri, so
|
||||
* see if the dot segments need to be reduced now.
|
||||
*/
|
||||
if(reduce_path && path) {
|
||||
DWORD current_path_len = (buffer+len) - path;
|
||||
DWORD new_path_len = remove_dot_segments(path, current_path_len);
|
||||
|
||||
/* Update the current length. */
|
||||
len -= (current_path_len-new_path_len);
|
||||
}
|
||||
|
||||
buffer[len++] = 0;
|
||||
|
||||
/* The null terminator isn't included the length. */
|
||||
*result_len = len-1;
|
||||
if(len > output_len)
|
||||
return STRSAFE_E_INSUFFICIENT_BUFFER;
|
||||
else
|
||||
memcpy(output, buffer, len*sizeof(WCHAR));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoInternetParseIUri (urlmon.@)
|
||||
*/
|
||||
|
@ -6089,6 +6194,7 @@ HRESULT WINAPI CoInternetParseIUri(IUri *pIUri, PARSEACTION ParseAction, DWORD d
|
|||
DWORD_PTR dwReserved)
|
||||
{
|
||||
HRESULT hr;
|
||||
Uri *uri;
|
||||
|
||||
TRACE("(%p %d %x %p %d %p %x)\n", pIUri, ParseAction, dwFlags, pwzResult,
|
||||
cchResult, pcchResult, (DWORD)dwReserved);
|
||||
|
@ -6102,6 +6208,15 @@ HRESULT WINAPI CoInternetParseIUri(IUri *pIUri, PARSEACTION ParseAction, DWORD d
|
|||
}
|
||||
|
||||
switch(ParseAction) {
|
||||
case PARSE_CANONICALIZE:
|
||||
if(!(uri = get_uri_obj(pIUri))) {
|
||||
*pcchResult = 0;
|
||||
FIXME("(%p %d %x %p %d %p %x) Unknown IUri's not supported for this action.\n",
|
||||
pIUri, ParseAction, dwFlags, pwzResult, cchResult, pcchResult, (DWORD)dwReserved);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
hr = parse_canonicalize(uri, dwFlags, pwzResult, cchResult, pcchResult);
|
||||
break;
|
||||
case PARSE_SECURITY_URL:
|
||||
case PARSE_MIME:
|
||||
case PARSE_SERVER:
|
||||
|
|
Loading…
Reference in New Issue