Commit fdfcfc6a authored by Thomas Mullaly's avatar Thomas Mullaly Committed by Alexandre Julliard

urlmon: Implemented canonicalization of query strings.

parent 36b1006c
...@@ -2921,6 +2921,216 @@ static const uri_properties uri_tests[] = { ...@@ -2921,6 +2921,216 @@ static const uri_properties uri_tests[] = {
{URL_SCHEME_HTTP,S_OK,FALSE}, {URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE}, {URLZONE_INVALID,E_NOTIMPL,FALSE},
} }
},
/* Forbidden characters in query aren't percent encoded for known scheme types with this flag. */
{ "http://www.winehq.org/tests/..?query=<|>&return=y", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=<|>&return=y",S_OK,TRUE},
{"?query=<|>&return=y",S_OK,TRUE},
{"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
{"http",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{80,S_OK,FALSE},
{URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Forbidden characters in query aren't percent encoded for known scheme types with this flag. */
{ "http://www.winehq.org/tests/..?query=<|>&return=y", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"http://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=<|>&return=y",S_OK,TRUE},
{"?query=<|>&return=y",S_OK,TRUE},
{"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
{"http",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{80,S_OK,FALSE},
{URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Forbidden characters are encoded for known scheme types. */
{ "http://www.winehq.org/tests/..?query=<|>&return=y", 0, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"http://www.winehq.org/?query=%3C%7C%3E&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"http://www.winehq.org/?query=%3C%7C%3E&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=%3C%7C%3E&return=y",S_OK,TRUE},
{"?query=%3C%7C%3E&return=y",S_OK,TRUE},
{"http://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
{"http",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{80,S_OK,FALSE},
{URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Forbidden characters are not encoded for unknown scheme types. */
{ "zip://www.winehq.org/tests/..?query=<|>&return=y", 0, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"zip://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"zip://www.winehq.org/?query=<|>&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=<|>&return=y",S_OK,TRUE},
{"?query=<|>&return=y",S_OK,TRUE},
{"zip://www.winehq.org/tests/..?query=<|>&return=y",S_OK,FALSE},
{"zip",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{0,S_FALSE,FALSE},
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Percent encoded, unreserved characters are decoded for known scheme types. */
{ "http://www.winehq.org/tests/..?query=%30%31&return=y", 0, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"http://www.winehq.org/?query=01&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"http://www.winehq.org/?query=01&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=01&return=y",S_OK,TRUE},
{"?query=01&return=y",S_OK,TRUE},
{"http://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
{"http",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{80,S_OK,FALSE},
{URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Percent encoded, unreserved characters aren't decoded for unknown scheme types. */
{ "zip://www.winehq.org/tests/..?query=%30%31&return=y", 0, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"zip://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"zip://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=%30%31&return=y",S_OK,TRUE},
{"?query=%30%31&return=y",S_OK,TRUE},
{"zip://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
{"zip",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{0,S_FALSE,FALSE},
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
},
/* Percent encoded characters aren't decoded when NO_DECODE_EXTRA_INFO is set. */
{ "http://www.winehq.org/tests/..?query=%30%31&return=y", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_HOST|
Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_PORT|Uri_HAS_QUERY|Uri_HAS_RAW_URI|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
TRUE,
{
{"http://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"http://www.winehq.org/?query=%30%31&return=y",S_OK,TRUE},
{"winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,TRUE},
{"www.winehq.org",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"/",S_OK,FALSE},
{"/?query=%30%31&return=y",S_OK,TRUE},
{"?query=%30%31&return=y",S_OK,TRUE},
{"http://www.winehq.org/tests/..?query=%30%31&return=y",S_OK,FALSE},
{"http",S_OK,FALSE},
{"",S_FALSE,FALSE},
{"",S_FALSE,FALSE}
},
{
{Uri_HOST_DNS,S_OK,FALSE},
{80,S_OK,FALSE},
{URL_SCHEME_HTTP,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE},
}
} }
}; };
......
...@@ -62,6 +62,9 @@ typedef struct { ...@@ -62,6 +62,9 @@ typedef struct {
INT path_start; INT path_start;
DWORD path_len; DWORD path_len;
INT extension_offset; INT extension_offset;
INT query_start;
DWORD query_len;
} Uri; } Uri;
typedef struct { typedef struct {
...@@ -2643,6 +2646,66 @@ static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags, ...@@ -2643,6 +2646,66 @@ static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags,
return TRUE; return TRUE;
} }
/* Attempts to canonicalize the query string of the URI.
*
* Things that happen:
* 1) For known scheme types forbidden characters
* are percent encoded, unless the NO_DECODE_EXTRA_INFO flag is set
* or NO_ENCODE_FORBIDDEN_CHARACTERS is set.
*
* 2) For known scheme types, percent encoded, unreserved characters
* are decoded as long as the NO_DECODE_EXTRA_INFO flag isn't set.
*/
static BOOL canonicalize_query(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
const WCHAR *ptr, *end;
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
if(!data->query) {
uri->query_start = -1;
uri->query_len = 0;
return TRUE;
}
uri->query_start = uri->canon_len;
end = data->query+data->query_len;
for(ptr = data->query; ptr < end; ++ptr) {
if(*ptr == '%') {
if(known_scheme && !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
WCHAR val = decode_pct_val(ptr);
if(is_unreserved(val)) {
if(!computeOnly)
uri->canon_uri[uri->canon_len] = val;
++uri->canon_len;
ptr += 2;
continue;
}
}
} else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr)) {
if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
!(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
if(!computeOnly)
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
uri->canon_len += 3;
continue;
}
}
if(!computeOnly)
uri->canon_uri[uri->canon_len] = *ptr;
++uri->canon_len;
}
uri->query_len = uri->canon_len - uri->query_start;
if(!computeOnly)
TRACE("(%p %p %x %d): Canonicalized query string %s len=%d\n", data, uri, flags,
computeOnly, debugstr_wn(uri->canon_uri+uri->query_start, uri->query_len),
uri->query_len);
return TRUE;
}
/* Canonicalizes the scheme information specified in the parse_data using the specified flags. */ /* Canonicalizes the scheme information specified in the parse_data using the specified flags. */
static BOOL canonicalize_scheme(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) { static BOOL canonicalize_scheme(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
uri->scheme_start = -1; uri->scheme_start = -1;
...@@ -2705,6 +2768,11 @@ static int compute_canonicalized_length(const parse_data *data, DWORD flags) { ...@@ -2705,6 +2768,11 @@ static int compute_canonicalized_length(const parse_data *data, DWORD flags) {
return -1; return -1;
} }
if(!canonicalize_query(data, &uri, flags, TRUE)) {
ERR("(%p %x): Failed to compute query string length.\n", data, flags);
return -1;
}
TRACE("(%p %x): Finished computing canonicalized URI length. length=%d\n", data, flags, uri.canon_len); TRACE("(%p %x): Finished computing canonicalized URI length. length=%d\n", data, flags, uri.canon_len);
return uri.canon_len; return uri.canon_len;
...@@ -2752,6 +2820,12 @@ static HRESULT canonicalize_uri(const parse_data *data, Uri *uri, DWORD flags) { ...@@ -2752,6 +2820,12 @@ static HRESULT canonicalize_uri(const parse_data *data, Uri *uri, DWORD flags) {
return E_INVALIDARG; return E_INVALIDARG;
} }
if(!canonicalize_query(data, uri, flags, FALSE)) {
ERR("(%p %p %x): Unable to canonicalize query string of the URI.\n",
data, uri, flags);
return E_INVALIDARG;
}
/* There's a possibility we didn't use all the space we allocated /* There's a possibility we didn't use all the space we allocated
* earlier. * earlier.
*/ */
......
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