Thomas Mullaly : urlmon: Improved support for determining if a URI is hierarchical or not.
Alexandre Julliard
julliard at winehq.org
Fri Aug 27 11:11:17 CDT 2010
Module: wine
Branch: master
Commit: 948009872dcd322c4eeeaa55da7e2117eafa13d0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=948009872dcd322c4eeeaa55da7e2117eafa13d0
Author: Thomas Mullaly <thomas.mullaly at 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/",S_OK,FALSE},
+ {"google.com",S_OK,FALSE},
+ {"http://google.com/",S_OK,FALSE},
+ {"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;
More information about the wine-cvs
mailing list