urlmon: Added a stub implementation for parsing the hier-part of a URI.

This commit is contained in:
Thomas Mullaly 2010-06-11 20:19:35 -04:00 committed by Alexandre Julliard
parent 0d0078380e
commit 9d363d52cd
2 changed files with 116 additions and 0 deletions

View File

@ -823,6 +823,36 @@ static const uri_properties uri_tests[] = {
{URL_SCHEME_WILDCARD,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE}
}
},
/* URI is considered opaque since CREATE_NO_CRACK_UNKNOWN_SCHEMES is set and its an unknown scheme. */
{ "zip://google.com", Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, S_OK, FALSE,
Uri_HAS_ABSOLUTE_URI|Uri_HAS_DISPLAY_URI|Uri_HAS_EXTENSION|Uri_HAS_PATH|
Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME_NAME|
Uri_HAS_SCHEME,
TRUE,
{
{"zip:/.//google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"zip:/.//google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{".com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE},
{"/.//google.com",S_OK,TRUE},
{"/.//google.com",S_OK,TRUE},
{"",S_FALSE,TRUE},
{"zip://google.com",S_OK,FALSE},
{"zip",S_OK,FALSE},
{"",S_FALSE,TRUE},
{"",S_FALSE,TRUE}
},
{
{Uri_HOST_UNKNOWN,S_OK,TRUE},
{0,S_FALSE,TRUE},
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE}
}
}
};

View File

@ -49,6 +49,8 @@ typedef struct {
BSTR uri;
BOOL is_relative;
BOOL is_opaque;
BOOL has_implicit_scheme;
const WCHAR *scheme;
DWORD scheme_len;
@ -104,6 +106,25 @@ static inline BOOL is_implicit_file_path(const WCHAR *str) {
return FALSE;
}
/* Checks if the URI is a hierarchical URI. A hierarchical
* URI is one that has "//" after the scheme.
*/
static BOOL check_hierarchical(const WCHAR **ptr) {
const WCHAR *start = *ptr;
if(**ptr != '/')
return FALSE;
++(*ptr);
if(**ptr != '/') {
*ptr = start;
return FALSE;
}
++(*ptr);
return TRUE;
}
/* Tries to parse the scheme name of the URI.
*
* scheme = ALPHA *(ALPHA | NUM | '+' | '-' | '.') as defined by RFC 3896.
@ -195,6 +216,8 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
if(flags & Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME) {
data->scheme = fileW;
data->scheme_len = lstrlenW(fileW);
data->has_implicit_scheme = TRUE;
TRACE("(%p %p %x): URI is an implicit file path.\n", ptr, data, flags);
} else {
/* Window's does not consider anything that can implicitly be a file
@ -213,6 +236,7 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
if(flags & Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME) {
data->scheme = wildcardW;
data->scheme_len = lstrlenW(wildcardW);
data->has_implicit_scheme = TRUE;
TRACE("(%p %p %x): URI is an implicit wildcard scheme.\n", ptr, data, flags);
} else if (flags & Uri_CREATE_ALLOW_RELATIVE) {
@ -235,6 +259,65 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags) {
return TRUE;
}
/* Determines how the URI should be parsed after the scheme information.
*
* If the scheme is followed, by "//" then, it is treated as an hierarchical URI
* which then the authority and path information will be parsed out. Otherwise, the
* URI will be treated as an opaque URI which the authority information is not parsed
* out.
*
* RFC 3896 defenition of hier-part:
*
* hier-part = "//" authority path-abempty
* / path-absolute
* / path-rootless
* / path-empty
*
* MSDN opaque URI definition:
* scheme ":" path [ "#" fragment ]
*
* NOTES:
* If the URI is of an unknown scheme type and has a "//" following the scheme then it
* is treated as a hierarchical URI, but, if the CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is
* set then it is considered an opaque URI reguardless of what follows the scheme information
* (per MSDN documentation).
*/
static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) {
/* Checks if the authority information needs to be parsed.
*
* Relative URI's aren't hierarchical URI's, but, they could trick
* "check_hierarchical" into thinking it is, so we need to explicitly
* make sure it's not relative. Also, if the URI is an implicit file
* scheme it might not contain a "//", but, it's considered hierarchical
* anyways. Wildcard Schemes are always considered hierarchical
*/
if(data->scheme_type == URL_SCHEME_WILDCARD ||
data->scheme_type == URL_SCHEME_FILE ||
(!data->is_relative && check_hierarchical(ptr))) {
/* Only treat it as a hierarchical URI if the scheme_type is known or
* the Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES flag is not set.
*/
if(data->scheme_type != URL_SCHEME_UNKNOWN ||
!(flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES)) {
TRACE("(%p %p %x): Treating URI as an hierarchical URI.\n", ptr, data, flags);
data->is_opaque = FALSE;
/* TODO: Handle hierarchical URI's, parse authority then parse the path. */
return TRUE;
}
}
/* If it reaches here, then the URI will be treated as an opaque
* URI.
*/
TRACE("(%p %p %x): Treating URI as an opaque URI.\n", ptr, data, flags);
data->is_opaque = TRUE;
/* TODO: Handle opaque URI's, parse path. */
return TRUE;
}
/* Parses and validates the components of the specified by data->uri
* and stores the information it parses into 'data'.
*
@ -252,6 +335,9 @@ static BOOL parse_uri(parse_data *data, DWORD flags) {
if(!parse_scheme(pptr, data, flags))
return FALSE;
if(!parse_hierpart(pptr, data, flags))
return FALSE;
TRACE("(%p %x): FINISHED PARSING URI.\n", data, flags);
return TRUE;
}