From 27ec56ea6bb15e5b8686baec186890f82035f35e Mon Sep 17 00:00:00 2001 From: Thomas Mullaly Date: Thu, 29 Jul 2010 16:36:39 -0400 Subject: [PATCH] urlmon: Implemented a fragment parser. --- dlls/urlmon/tests/uri.c | 34 ++++++++++++++++++++++++++++++- dlls/urlmon/uri.c | 45 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c index ab0125d9a2e..196e4d8f6f9 100644 --- a/dlls/urlmon/tests/uri.c +++ b/dlls/urlmon/tests/uri.c @@ -3160,6 +3160,36 @@ static const uri_properties uri_tests[] = { {URL_SCHEME_HTTP,S_OK,FALSE}, {URLZONE_INVALID,E_NOTIMPL,FALSE}, } + }, + /* Unknown scheme types can have invalid % encoded data in fragments. */ + { "zip://www.winehq.org/tests/#Te%xx", 0, S_OK, FALSE, + Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT| + Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI| + Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME, + TRUE, + { + {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE}, + {"www.winehq.org",S_OK,FALSE}, + {"zip://www.winehq.org/tests/#Te%xx",S_OK,TRUE}, + {"winehq.org",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"#Te%xx",S_OK,TRUE}, + {"www.winehq.org",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"/tests/",S_OK,FALSE}, + {"/tests/",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"zip://www.winehq.org/tests/#Te%xx",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}, + } } }; @@ -3214,7 +3244,9 @@ static const invalid_uri invalid_uri_tests[] = { {"news:test%XX",0,FALSE}, {"mailto:wine@winehq%G8.com",0,FALSE}, /* Known scheme types can't have invalid % encoded data in query string. */ - {"http://google.com/?query=te%xx",0,FALSE} + {"http://google.com/?query=te%xx",0,FALSE}, + /* Invalid % encoded data in fragment of know scheme type. */ + {"ftp://google.com/#Test%xx",0,FALSE} }; typedef struct _uri_equality { diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c index 51e58d50881..ecf69223c45 100644 --- a/dlls/urlmon/uri.c +++ b/dlls/urlmon/uri.c @@ -126,6 +126,9 @@ typedef struct { const WCHAR *query; DWORD query_len; + + const WCHAR *fragment; + DWORD fragment_len; } parse_data; static const CHAR hexDigits[] = "0123456789ABCDEF"; @@ -1783,6 +1786,45 @@ static BOOL parse_query(const WCHAR **ptr, parse_data *data, DWORD flags) { return TRUE; } +/* Attempts to parse the fragment from the URI. + * + * NOTES: + * If NO_DECODE_EXTRA_INFO flag is set, then invalid percent encoded + * data is allowed appear in the query string. For unknown scheme types + * invalid percent encoded data is allowed to appear reguardless. + */ +static BOOL parse_fragment(const WCHAR **ptr, parse_data *data, DWORD flags) { + const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN; + + if(**ptr != '#') { + TRACE("(%p %p %x): URI didn't contain a fragment.\n", ptr, data, flags); + return TRUE; + } + + data->fragment = *ptr; + + ++(*ptr); + while(**ptr) { + if(**ptr == '%' && known_scheme && + !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) { + if(!check_pct_encoded(ptr)) { + *ptr = data->fragment; + data->fragment = NULL; + return FALSE; + } else + continue; + } + + ++(*ptr); + } + + data->fragment_len = *ptr - data->fragment; + + TRACE("(%p %p %x): Parsed fragment %s len=%d\n", ptr, data, flags, + debugstr_wn(data->fragment, data->fragment_len), data->fragment_len); + return TRUE; +} + /* Parses and validates the components of the specified by data->uri * and stores the information it parses into 'data'. * @@ -1806,7 +1848,8 @@ static BOOL parse_uri(parse_data *data, DWORD flags) { if(!parse_query(pptr, data, flags)) return FALSE; - /* TODO: Parse fragment (if the URI has one). */ + if(!parse_fragment(pptr, data, flags)) + return FALSE; TRACE("(%p %x): FINISHED PARSING URI.\n", data, flags); return TRUE;