urlmon: Added implementation for PARSE_CANONICALIZE in CoInternetParseIUri.

This commit is contained in:
Thomas Mullaly 2010-11-15 16:51:56 -05:00 committed by Alexandre Julliard
parent 4e07082eda
commit 8cf81d912f
2 changed files with 203 additions and 0 deletions

View File

@ -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");

View File

@ -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: