urlmon: IUriBuilder_CreateUri* functions return base IUri if there were no changes.

This commit is contained in:
Thomas Mullaly 2010-09-17 16:54:39 -04:00 committed by Alexandre Julliard
parent 2e1f854860
commit 947e4ec567
2 changed files with 222 additions and 86 deletions

View File

@ -4862,9 +4862,9 @@ static const uri_builder_test uri_builder_tests[] = {
{FALSE},
},
{FALSE},
0,S_OK,TRUE,
0,S_OK,TRUE,
0,0,0,S_OK,TRUE,
0,S_OK,FALSE,
0,S_OK,FALSE,
0,0,0,S_OK,FALSE,
{
{"http://:password@google.com/",S_OK},
{":password@google.com",S_OK},
@ -4929,9 +4929,9 @@ static const uri_builder_test uri_builder_tests[] = {
{TRUE,NULL,"zip",Uri_PROPERTY_SCHEME_NAME,E_INVALIDARG,FALSE}
},
{FALSE},
0,S_OK,TRUE,
0,S_OK,TRUE,
0,0,0,S_OK,TRUE,
0,S_OK,FALSE,
0,S_OK,FALSE,
0,0,0,S_OK,FALSE,
{
{"zip://google.com/",S_OK},
{"google.com",S_OK},
@ -4962,9 +4962,9 @@ static const uri_builder_test uri_builder_tests[] = {
{TRUE,"","zip",Uri_PROPERTY_SCHEME_NAME,E_INVALIDARG,FALSE}
},
{FALSE},
0,S_OK,TRUE,
0,S_OK,TRUE,
0,0,0,S_OK,TRUE,
0,S_OK,FALSE,
0,S_OK,FALSE,
0,0,0,S_OK,FALSE,
{
{"zip://google.com/",S_OK},
{"google.com",S_OK},
@ -4988,6 +4988,103 @@ static const uri_builder_test uri_builder_tests[] = {
{URL_SCHEME_UNKNOWN,S_OK},
{URLZONE_INVALID,E_NOTIMPL}
}
},
/* -1 to CreateUri makes it use the same flags as the base IUri was created with.
* CreateUriSimple always uses the flags the base IUri was created with (if any).
*/
{ "http://google.com/../../",Uri_CREATE_NO_CANONICALIZE,S_OK,FALSE,
{{FALSE}},
{FALSE},
-1,S_OK,FALSE,
0,S_OK,FALSE,
0,UriBuilder_USE_ORIGINAL_FLAGS,0,S_OK,FALSE,
{
{"http://google.com/../../",S_OK},
{"google.com",S_OK},
{"http://google.com/../../",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"",S_FALSE},
{"google.com",S_OK},
{"",S_FALSE},
{"/../../",S_OK},
{"/../../",S_OK},
{"",S_FALSE},
{"http://google.com/../../",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}
}
},
{ "http://google.com/",0,S_OK,FALSE,
{
{TRUE,"#Fr<|>g",NULL,Uri_PROPERTY_FRAGMENT,S_OK,FALSE}
},
{FALSE},
-1,S_OK,TRUE,
0,S_OK,TRUE,
Uri_CREATE_NO_DECODE_EXTRA_INFO,UriBuilder_USE_ORIGINAL_FLAGS,0,S_OK,TRUE,
{
{"http://google.com/#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"http://google.com/#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"/",S_OK},
{"/",S_OK},
{"",S_FALSE},
{"http://google.com/#Fr<|>g",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}
}
},
{ "http://google.com/",0,S_OK,FALSE,
{
{TRUE,"#Fr<|>g",NULL,Uri_PROPERTY_FRAGMENT,S_OK,FALSE}
},
{FALSE},
Uri_CREATE_CANONICALIZE|Uri_CREATE_NO_CANONICALIZE,E_INVALIDARG,FALSE,
0,S_OK,TRUE,
Uri_CREATE_CANONICALIZE|Uri_CREATE_NO_CANONICALIZE,UriBuilder_USE_ORIGINAL_FLAGS,0,S_OK,TRUE,
{
{"http://google.com/#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"http://google.com/#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"#Fr%3C%7C%3Eg",S_OK},
{"google.com",S_OK},
{"",S_FALSE},
{"/",S_OK},
{"/",S_OK},
{"",S_FALSE},
{"http://google.com/#Fr<|>g",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}
}
}
};
@ -5023,29 +5120,29 @@ static const uri_builder_remove_test uri_builder_remove_tests[] = {
/* Doesn't remove the whole userinfo component. */
{ "http://username:pass@google.com/",0,S_OK,FALSE,
Uri_HAS_USER_INFO,S_OK,FALSE,
"http://username:pass@google.com/",0,S_OK,TRUE
"http://username:pass@google.com/",0,S_OK,FALSE
},
/* Doesn't remove the domain. */
{ "http://google.com/",0,S_OK,FALSE,
Uri_HAS_DOMAIN,S_OK,FALSE,
"http://google.com/",0,S_OK,TRUE
"http://google.com/",0,S_OK,FALSE
},
{ "http://google.com:120/",0,S_OK,FALSE,
Uri_HAS_AUTHORITY,S_OK,FALSE,
"http://google.com:120/",0,S_OK,TRUE
"http://google.com:120/",0,S_OK,FALSE
},
{ "http://google.com/test.com/",0,S_OK,FALSE,
Uri_HAS_EXTENSION,S_OK,FALSE,
"http://google.com/test.com/",0,S_OK,TRUE
"http://google.com/test.com/",0,S_OK,FALSE
},
{ "http://google.com/?test=x",0,S_OK,FALSE,
Uri_HAS_PATH_AND_QUERY,S_OK,FALSE,
"http://google.com/?test=x",0,S_OK,TRUE
"http://google.com/?test=x",0,S_OK,FALSE
},
/* Can't remove the scheme name. */
{ "http://google.com/?test=x",0,S_OK,FALSE,
Uri_HAS_SCHEME_NAME|Uri_HAS_QUERY,E_INVALIDARG,FALSE,
"http://google.com/?test=x",0,S_OK,TRUE
"http://google.com/?test=x",0,S_OK,FALSE
}
};
@ -6664,28 +6761,22 @@ static void test_IUriBuilder_CreateInvalidArgs(void) {
/* No longer returns E_NOTIMPL, since a IUri has been set and hasn't been modified. */
uri = NULL;
hr = IUriBuilder_CreateUri(builder, 0, Uri_HAS_USER_NAME, 0, &uri);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
}
todo_wine { ok(uri != NULL, "Error: The uri was NULL.\n"); }
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
ok(uri != NULL, "Error: The uri was NULL.\n");
if(uri) IUri_Release(uri);
uri = NULL;
hr = IUriBuilder_CreateUriSimple(builder, Uri_HAS_USER_NAME, 0, &uri);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUriSimple returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
}
todo_wine { ok(uri != NULL, "Error: uri was NULL.\n"); }
ok(hr == S_OK, "Error: IUriBuilder_CreateUriSimple returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
ok(uri != NULL, "Error: uri was NULL.\n");
if(uri) IUri_Release(uri);
uri = NULL;
hr = IUriBuilder_CreateUriWithFlags(builder, 0, 0, 0, 0, &uri);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
}
todo_wine { ok(uri != NULL, "Error: uri was NULL.\n"); }
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
ok(uri != NULL, "Error: uri was NULL.\n");
if(uri) IUri_Release(uri);
hr = IUriBuilder_SetFragment(builder, NULL);
@ -7920,9 +8011,7 @@ static void test_IUriBuilder_IUriProperty(void) {
orig_count = get_refcnt(uri);
hr = IUriBuilder_CreateUri(builder, 0, 0, 0, &test);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
}
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",
@ -7932,6 +8021,17 @@ static void test_IUriBuilder_IUriProperty(void) {
}
if(test) IUri_Release(test);
test = NULL;
hr = IUriBuilder_CreateUri(builder, -1, 0, 0, &test);
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",
orig_count+1, cur_count);
ok(test == uri, "Error: Expected test to be %p, but was %p instead.\n", uri, test);
}
if(test) IUri_Release(test);
/* Doesn't return the same IUri, if the flag combination is different then the one that created
* the base IUri.
*/
@ -7952,9 +8052,7 @@ static void test_IUriBuilder_IUriProperty(void) {
*/
test = NULL;
hr = IUriBuilder_CreateUri(builder, Uri_CREATE_CANONICALIZE, 0, 0, &test);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
}
ok(hr == S_OK, "Error: IUriBuilder_CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",
@ -7965,9 +8063,7 @@ static void test_IUriBuilder_IUriProperty(void) {
test = NULL;
hr = IUriBuilder_CreateUriSimple(builder, 0, 0, &test);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUriSimple returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
}
ok(hr == S_OK, "Error: IUriBuilder_CreateUriSimple returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",
@ -7978,10 +8074,8 @@ static void test_IUriBuilder_IUriProperty(void) {
test = NULL;
hr = IUriBuilder_CreateUriWithFlags(builder, 0, 0, 0, 0, &test);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
}
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n",
hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",
@ -8010,9 +8104,7 @@ static void test_IUriBuilder_IUriProperty(void) {
*/
test = NULL;
hr = IUriBuilder_CreateUriWithFlags(builder, Uri_CREATE_CANONICALIZE, 0, 0, 0, &test);
todo_wine {
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
}
ok(hr == S_OK, "Error: IUriBuilder_CreateUriWithFlags returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
if(SUCCEEDED(hr)) {
cur_count = get_refcnt(uri);
ok(cur_count == orig_count+1, "Error: Expected uri ref count to be %d, but was %d instead.\n",

View File

@ -41,6 +41,7 @@ typedef struct {
DWORD canon_size;
DWORD canon_len;
BOOL display_absolute;
DWORD create_flags;
INT scheme_start;
DWORD scheme_len;
@ -335,6 +336,31 @@ static inline BOOL is_hierarchical_scheme(URL_SCHEME type) {
type == URL_SCHEME_RES);
}
/* Checks if 'flags' contains an invalid combination of Uri_CREATE flags. */
static inline BOOL has_invalid_flag_combination(DWORD flags) {
return((flags & Uri_CREATE_DECODE_EXTRA_INFO && flags & Uri_CREATE_NO_DECODE_EXTRA_INFO) ||
(flags & Uri_CREATE_CANONICALIZE && flags & Uri_CREATE_NO_CANONICALIZE) ||
(flags & Uri_CREATE_CRACK_UNKNOWN_SCHEMES && flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES) ||
(flags & Uri_CREATE_PRE_PROCESS_HTML_URI && flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI) ||
(flags & Uri_CREATE_IE_SETTINGS && flags & Uri_CREATE_NO_IE_SETTINGS));
}
/* Applies each default Uri_CREATE flags to 'flags' if it
* doesn't cause a flag conflict.
*/
static void apply_default_flags(DWORD *flags) {
if(!(*flags & Uri_CREATE_NO_CANONICALIZE))
*flags |= Uri_CREATE_CANONICALIZE;
if(!(*flags & Uri_CREATE_NO_DECODE_EXTRA_INFO))
*flags |= Uri_CREATE_DECODE_EXTRA_INFO;
if(!(*flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES))
*flags |= Uri_CREATE_CRACK_UNKNOWN_SCHEMES;
if(!(*flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI))
*flags |= Uri_CREATE_PRE_PROCESS_HTML_URI;
if(!(*flags & Uri_CREATE_IE_SETTINGS))
*flags |= Uri_CREATE_NO_IE_SETTINGS;
}
/* Determines if the URI is hierarchical using the information already parsed into
* data and using the current location of parsing in the URI string.
*
@ -3381,6 +3407,40 @@ static void reset_builder(UriBuilder *builder) {
builder->modified_props = 0;
}
static HRESULT build_uri(const UriBuilder *builder, IUri **uri, DWORD create_flags,
DWORD use_orig_flags, DWORD encoding_mask)
{
if(!uri)
return E_POINTER;
if(encoding_mask && (!builder->uri || builder->modified_props)) {
*uri = NULL;
return E_NOTIMPL;
}
/* Decide what flags should be used when creating the Uri. */
if((use_orig_flags & UriBuilder_USE_ORIGINAL_FLAGS) && builder->uri)
create_flags = builder->uri->create_flags;
else {
if(has_invalid_flag_combination(create_flags)) {
*uri = NULL;
return E_INVALIDARG;
}
/* Set the default flags if they don't cause a conflict. */
apply_default_flags(&create_flags);
}
/* Return the base IUri if no changes have been made and the create_flags match. */
if(builder->uri && !builder->modified_props && builder->uri->create_flags == create_flags) {
*uri = URI(builder->uri);
IUri_AddRef(*uri);
return S_OK;
}
return E_NOTIMPL;
}
#define URI_THIS(iface) DEFINE_THIS(Uri, IUri, iface)
static HRESULT WINAPI Uri_QueryInterface(IUri *iface, REFIID riid, void **ppv)
@ -4246,11 +4306,7 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU
}
/* Check for invalid flags. */
if((dwFlags & Uri_CREATE_DECODE_EXTRA_INFO && dwFlags & Uri_CREATE_NO_DECODE_EXTRA_INFO) ||
(dwFlags & Uri_CREATE_CANONICALIZE && dwFlags & Uri_CREATE_NO_CANONICALIZE) ||
(dwFlags & Uri_CREATE_CRACK_UNKNOWN_SCHEMES && dwFlags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES) ||
(dwFlags & Uri_CREATE_PRE_PROCESS_HTML_URI && dwFlags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI) ||
(dwFlags & Uri_CREATE_IE_SETTINGS && dwFlags & Uri_CREATE_NO_IE_SETTINGS)) {
if(has_invalid_flag_combination(dwFlags)) {
*ppURI = NULL;
return E_INVALIDARG;
}
@ -4266,6 +4322,9 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU
ret->lpIUriVtbl = &UriVtbl;
ret->ref = 1;
/* Explicitly set the default flags if it doesn't cause a flag conflict. */
apply_default_flags(&dwFlags);
/* Pre process the URI, unless told otherwise. */
if(!(dwFlags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI))
ret->raw_uri = pre_process_uri(pwzURI);
@ -4298,6 +4357,8 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU
return hr;
}
ret->create_flags = dwFlags;
*ppURI = URI(ret);
return S_OK;
}
@ -4436,19 +4497,13 @@ static HRESULT WINAPI UriBuilder_CreateUriSimple(IUriBuilder *iface,
IUri **ppIUri)
{
UriBuilder *This = URIBUILDER_THIS(iface);
HRESULT hr;
TRACE("(%p)->(%d %d %p)\n", This, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
if(!ppIUri)
return E_POINTER;
/* Acts the same way as CreateUri. */
if(dwAllowEncodingPropertyMask && (!This->uri || This->modified_props)) {
*ppIUri = NULL;
return E_NOTIMPL;
}
FIXME("(%p)->(%d %d %p)\n", This, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return E_NOTIMPL;
hr = build_uri(This, ppIUri, 0, UriBuilder_USE_ORIGINAL_FLAGS, dwAllowEncodingPropertyMask);
if(hr == E_NOTIMPL)
FIXME("(%p)->(%d %d %p)\n", This, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return hr;
}
static HRESULT WINAPI UriBuilder_CreateUri(IUriBuilder *iface,
@ -4458,22 +4513,17 @@ static HRESULT WINAPI UriBuilder_CreateUri(IUriBuilder *iface,
IUri **ppIUri)
{
UriBuilder *This = URIBUILDER_THIS(iface);
HRESULT hr;
TRACE("(%p)->(0x%08x %d %d %p)\n", This, dwCreateFlags, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
if(!ppIUri)
return E_POINTER;
if(dwCreateFlags == -1)
hr = build_uri(This, ppIUri, 0, UriBuilder_USE_ORIGINAL_FLAGS, dwAllowEncodingPropertyMask);
else
hr = build_uri(This, ppIUri, dwCreateFlags, 0, dwAllowEncodingPropertyMask);
/* The only time it doesn't return E_NOTIMPL when the dwAllow parameter
* has flags set, is when the IUriBuilder has a IUri set and it hasn't
* been modified (a call to a "Set*" hasn't been performed).
*/
if(dwAllowEncodingPropertyMask && (!This->uri || This->modified_props)) {
*ppIUri = NULL;
return E_NOTIMPL;
}
FIXME("(%p)->(0x%08x %d %d %p)\n", This, dwCreateFlags, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return E_NOTIMPL;
if(hr == E_NOTIMPL)
FIXME("(%p)->(0x%08x %d %d %p)\n", This, dwCreateFlags, dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return hr;
}
static HRESULT WINAPI UriBuilder_CreateUriWithFlags(IUriBuilder *iface,
@ -4484,21 +4534,15 @@ static HRESULT WINAPI UriBuilder_CreateUriWithFlags(IUriBuilder *iface,
IUri **ppIUri)
{
UriBuilder *This = URIBUILDER_THIS(iface);
HRESULT hr;
TRACE("(%p)->(0x%08x 0x%08x %d %d %p)\n", This, dwCreateFlags, dwUriBuilderFlags,
dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
if(!ppIUri)
return E_POINTER;
/* Same as CreateUri. */
if(dwAllowEncodingPropertyMask && (!This->uri || This->modified_props)) {
*ppIUri = NULL;
return E_NOTIMPL;
}
FIXME("(%p)->(0x%08x 0x%08x %d %d %p)\n", This, dwCreateFlags, dwUriBuilderFlags,
dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return E_NOTIMPL;
hr = build_uri(This, ppIUri, dwCreateFlags, dwUriBuilderFlags, dwAllowEncodingPropertyMask);
if(hr == E_NOTIMPL)
FIXME("(%p)->(0x%08x 0x%08x %d %d %p)\n", This, dwCreateFlags, dwUriBuilderFlags,
dwAllowEncodingPropertyMask, (DWORD)dwReserved, ppIUri);
return hr;
}
static HRESULT WINAPI UriBuilder_GetIUri(IUriBuilder *iface, IUri **ppIUri)