urlmon: Finished adding basic support for Uri_CREATE_FILE_USE_DOS_PATH.
diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c
index 54f5ef4..7a7bfb1 100644
--- a/dlls/urlmon/tests/uri.c
+++ b/dlls/urlmon/tests/uri.c
@@ -3887,6 +3887,64 @@
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
{URLZONE_INVALID,E_NOTIMPL,FALSE}
}
+ },
+ /* Dot segements aren't removed. */
+ { "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}
+ }
+ },
+ /* Forbidden characters aren't percent encoded. */
+ { "file://c:\\dir\\i^|ndex.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\\i^|ndex.html",S_OK,FALSE},
+ {"",S_FALSE,FALSE},
+ {"file://c:\\dir\\i^|ndex.html",S_OK,FALSE},
+ {"",S_FALSE,FALSE},
+ {".html",S_OK,FALSE},
+ {"",S_FALSE,FALSE},
+ {"",S_FALSE,FALSE},
+ {"",S_FALSE,FALSE},
+ {"c:\\dir\\i^|ndex.html",S_OK,FALSE},
+ {"c:\\dir\\i^|ndex.html",S_OK,FALSE},
+ {"",S_FALSE,FALSE},
+ {"file://c:\\dir\\i^|ndex.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}
+ }
}
};
@@ -3945,7 +4003,10 @@
/* Invalid % encoded data in fragment of know scheme type. */
{"ftp://google.com/#Test%xx",0,FALSE},
{" http://google.com/",Uri_CREATE_NO_PRE_PROCESS_HTML_URI,FALSE},
- {"\n\nhttp://google.com/",Uri_CREATE_NO_PRE_PROCESS_HTML_URI,FALSE}
+ {"\n\nhttp://google.com/",Uri_CREATE_NO_PRE_PROCESS_HTML_URI,FALSE},
+ {"file://c:\\test<test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
+ {"file://c:\\test>test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE},
+ {"file://c:\\test\"test",Uri_CREATE_FILE_USE_DOS_PATH,FALSE}
};
typedef struct _uri_equality {
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index f184aab..3a728f5 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -1776,6 +1776,7 @@
static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD flags) {
const WCHAR *start = *ptr;
static const WCHAR slash[] = {'/',0};
+ const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
if(is_path_delim(**ptr)) {
if(data->scheme_type == URL_SCHEME_WILDCARD) {
@@ -1791,13 +1792,19 @@
}
} else {
while(!is_path_delim(**ptr)) {
- if(**ptr == '%' && data->scheme_type != URL_SCHEME_UNKNOWN &&
- data->scheme_type != URL_SCHEME_FILE) {
+ if(**ptr == '%' && data->scheme_type != URL_SCHEME_UNKNOWN && !is_file) {
if(!check_pct_encoded(ptr)) {
*ptr = start;
return FALSE;
} else
continue;
+ } else if((**ptr == '>' || **ptr == '<' || **ptr == '\"') && is_file &&
+ (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
+ /* File schemes with USE_DOS_PATH set aren't allowed to have
+ * a '<' or '>' or '\"' appear in them.
+ */
+ *ptr = start;
+ return FALSE;
} else if(**ptr == '\\') {
/* Not allowed to have a backslash if NO_CANONICALIZE is set
* and the scheme is known type (but not a file scheme).
@@ -2742,10 +2749,17 @@
}
} else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) || is_file)) {
- /* Escape the forbidden character. */
- if(!computeOnly)
- pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
- uri->canon_len += 3;
+ if(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
+ /* Don't escape the character. */
+ if(!computeOnly)
+ uri->canon_uri[uri->canon_len] = *ptr;
+ ++uri->canon_len;
+ } else {
+ /* Escape the forbidden character. */
+ if(!computeOnly)
+ pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
+ uri->canon_len += 3;
+ }
} else {
if(!computeOnly)
uri->canon_uri[uri->canon_len] = *ptr;
@@ -2756,10 +2770,12 @@
uri->path_len = uri->canon_len - uri->path_start;
/* Removing the dot segments only happens when it's not in
- * computeOnly mode and it's not a wildcard scheme.
+ * computeOnly mode and it's not a wildcard scheme. File schemes
+ * with USE_DOS_PATH set don't get dot segments removed.
*/
- if(!computeOnly && data->scheme_type != URL_SCHEME_WILDCARD) {
- if(!(flags & Uri_CREATE_NO_CANONICALIZE)) {
+ if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) &&
+ data->scheme_type != URL_SCHEME_WILDCARD) {
+ if(!(flags & Uri_CREATE_NO_CANONICALIZE) && !computeOnly) {
/* Remove the dot segments (if any) and reset everything to the new
* correct length.
*/