Module: wine Branch: master Commit: 948009872dcd322c4eeeaa55da7e2117eafa13d0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=948009872dcd322c4eeeaa55da...
Author: Thomas Mullaly thomas.mullaly@gmail.com Date: Wed Aug 25 21:12:46 2010 -0400
urlmon: Improved support for determining if a URI is hierarchical or not.
---
dlls/urlmon/tests/uri.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/urlmon/uri.c | 44 ++++++++++++------ 2 files changed, 145 insertions(+), 15 deletions(-)
diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c index 11a464e..54f5ef4 100644 --- a/dlls/urlmon/tests/uri.c +++ b/dlls/urlmon/tests/uri.c @@ -3771,6 +3771,122 @@ static const uri_properties uri_tests[] = { {URL_SCHEME_FILE,S_OK,FALSE}, {URLZONE_INVALID,E_NOTIMPL,FALSE} } + }, + /* The backslashes after the scheme name are converted to forward slashes. */ + { "file:\\c:\dir\index.html", Uri_CREATE_FILE_USE_DOS_PATH, 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_SCHEME_NAME|Uri_HAS_HOST_TYPE + |Uri_HAS_SCHEME, FALSE, + { + {"file://c:\dir\index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file://c:\dir\index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {".html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"c:\dir\index.html",S_OK,FALSE}, + {"c:\dir\index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file:\\c:\dir\index.html",S_OK,FALSE}, + {"file",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {0,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_FILE,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, + { "file:\\c:/dir/index.html", 0, 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_SCHEME_NAME|Uri_HAS_HOST_TYPE + |Uri_HAS_SCHEME, FALSE, + { + {"file:///c:/dir/index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file:///c:/dir/index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {".html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"/c:/dir/index.html",S_OK,FALSE}, + {"/c:/dir/index.html",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file:\\c:/dir/index.html",S_OK,FALSE}, + {"file",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {0,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_FILE,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, + { "http:\\google.com", 0, S_OK, FALSE, + Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN| + Uri_HAS_HOST|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|Uri_HAS_SCHEME_NAME| + Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME, + FALSE, + { + {"http://google.com/%22,S_OK,FALSE%7D, + {"google.com",S_OK,FALSE}, + {"http://google.com/%22,S_OK,FALSE%7D, + {"google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"/",S_OK,FALSE}, + {"/",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"http:\\google.com",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} + } + }, + /* the "\\" aren't converted to "//" for unknown scheme types and it's considered opaque. */ + { "zip:\\google.com", 0, 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_SCHEME_NAME|Uri_HAS_SCHEME| + Uri_HAS_HOST_TYPE, + FALSE, + { + {"zip:\\google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"zip:\\google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {".com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"\\google.com",S_OK,FALSE}, + {"\\google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"zip:\\google.com",S_OK,FALSE}, + {"zip",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_UNKNOWN,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } } };
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c index 530b1ad..f184aab 100644 --- a/dlls/urlmon/uri.c +++ b/dlls/urlmon/uri.c @@ -306,6 +306,33 @@ static inline BOOL is_hierarchical_scheme(URL_SCHEME type) { type == URL_SCHEME_RES); }
+/* Determines if the URI is hierarchical using the information already parsed into + * data and using the current location of parsing in the URI string. + * + * Windows considers a URI hierarchical if on of the following is true: + * A.) It's a wildcard scheme. + * B.) It's an implicit file scheme. + * C.) It's a known hierarchical scheme and it has two '\' after the scheme name. + * (the '\' will be converted into "//" during canonicalization). + * D.) It's not a relative URI and "//" appears after the scheme name. + */ +static inline BOOL is_hierarchical_uri(const WCHAR **ptr, const parse_data *data) { + const WCHAR *start = *ptr; + + if(data->scheme_type == URL_SCHEME_WILDCARD) + return TRUE; + else if(data->scheme_type == URL_SCHEME_FILE && data->has_implicit_scheme) + return TRUE; + else if(is_hierarchical_scheme(data->scheme_type) && (*ptr)[0] == '\' && (*ptr)[1] == '\') { + *ptr += 2; + return TRUE; + } else if(!data->is_relative && check_hierarchical(ptr)) + return TRUE; + + *ptr = start; + return FALSE; +} + /* Checks if the two Uri's are logically equivalent. It's a simple * comparison, since they are both of type Uri, and it can access * the properties of each Uri directly without the need to go @@ -1866,17 +1893,8 @@ static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags) static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) { const WCHAR *start = *ptr;
- /* 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 && is_implicit_file_path(*ptr)) || - (!data->is_relative && check_hierarchical(ptr))) { + /* Checks if the authority information needs to be parsed. */ + if(is_hierarchical_uri(ptr, data)) { /* 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. */ @@ -1885,10 +1903,6 @@ static BOOL parse_hierpart(const WCHAR **ptr, parse_data *data, DWORD flags) { TRACE("(%p %p %x): Treating URI as an hierarchical URI.\n", ptr, data, flags); data->is_opaque = FALSE;
- if(data->scheme_type == URL_SCHEME_FILE) - /* Skip past the "//" after the scheme (if any). */ - check_hierarchical(ptr); - /* TODO: Handle hierarchical URI's, parse authority then parse the path. */ if(!parse_authority(ptr, data, flags)) return FALSE;