mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
urlmon: Improved support for opaque file URL paths.
This commit is contained in:
parent
fe89d8ac5b
commit
144ddea3f9
@ -3945,6 +3945,90 @@ static const uri_properties uri_tests[] = {
|
|||||||
{URL_SCHEME_FILE,S_OK,FALSE},
|
{URL_SCHEME_FILE,S_OK,FALSE},
|
||||||
{URLZONE_INVALID,E_NOTIMPL,FALSE}
|
{URLZONE_INVALID,E_NOTIMPL,FALSE}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/* The '\' are still converted to '/' even though it's an opaque file URI. */
|
||||||
|
{ "file:c:\\dir\\../..\\index.html", 0, S_OK, FALSE,
|
||||||
|
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,
|
||||||
|
{
|
||||||
|
{"",S_FALSE,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}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* '/' are still converted to '\' even though it's an opaque URI. */
|
||||||
|
{ "file:c:/dir\\../..\\index.html", Uri_CREATE_FILE_USE_DOS_PATH, S_OK, FALSE,
|
||||||
|
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,
|
||||||
|
{
|
||||||
|
{"",S_FALSE,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:\\in^|dex.html", Uri_CREATE_FILE_USE_DOS_PATH, S_OK, FALSE,
|
||||||
|
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,
|
||||||
|
{
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"file:c:\\in^|dex.html",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{".html",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"c:\\in^|dex.html",S_OK,FALSE},
|
||||||
|
{"c:\\in^|dex.html",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"file:c:\\in^|dex.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}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4006,7 +4090,10 @@ static const invalid_uri invalid_uri_tests[] = {
|
|||||||
{"\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},
|
{"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},
|
||||||
|
{"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 {
|
typedef struct _uri_equality {
|
||||||
|
@ -224,6 +224,10 @@ static inline BOOL is_unc_path(const WCHAR *str) {
|
|||||||
return (str[0] == '\\' && str[0] == '\\');
|
return (str[0] == '\\' && str[0] == '\\');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOL is_forbidden_dos_path_char(WCHAR val) {
|
||||||
|
return (val == '>' || val == '<' || val == '\"');
|
||||||
|
}
|
||||||
|
|
||||||
/* A URI is implicitly a file path if it begins with
|
/* A URI is implicitly a file path if it begins with
|
||||||
* a drive letter (eg X:) or starts with "\\" (UNC path).
|
* a drive letter (eg X:) or starts with "\\" (UNC path).
|
||||||
*/
|
*/
|
||||||
@ -1798,7 +1802,7 @@ static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD f
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
} else if((**ptr == '>' || **ptr == '<' || **ptr == '\"') && is_file &&
|
} else if(is_forbidden_dos_path_char(**ptr) && is_file &&
|
||||||
(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
/* File schemes with USE_DOS_PATH set aren't allowed to have
|
/* File schemes with USE_DOS_PATH set aren't allowed to have
|
||||||
* a '<' or '>' or '\"' appear in them.
|
* a '<' or '>' or '\"' appear in them.
|
||||||
@ -1849,9 +1853,13 @@ static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD f
|
|||||||
* NOTE:
|
* NOTE:
|
||||||
* Windows allows invalid % encoded data to appear in opaque URI paths
|
* Windows allows invalid % encoded data to appear in opaque URI paths
|
||||||
* for unknown scheme types.
|
* for unknown scheme types.
|
||||||
|
*
|
||||||
|
* File schemes with USE_DOS_PATH set aren't allowed to have '<', '>', or '\"'
|
||||||
|
* appear in them.
|
||||||
*/
|
*/
|
||||||
static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags) {
|
static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags) {
|
||||||
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
||||||
|
const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
|
||||||
|
|
||||||
data->path = *ptr;
|
data->path = *ptr;
|
||||||
|
|
||||||
@ -1863,6 +1871,11 @@ static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
|
} else if(is_forbidden_dos_path_char(**ptr) && is_file &&
|
||||||
|
(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
|
*ptr = data->path;
|
||||||
|
data->path = NULL;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
++(*ptr);
|
++(*ptr);
|
||||||
@ -2804,10 +2817,17 @@ static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
|
|||||||
*
|
*
|
||||||
* 3) '\\' are changed to '/' for known scheme types
|
* 3) '\\' are changed to '/' for known scheme types
|
||||||
* except for mailto schemes.
|
* except for mailto schemes.
|
||||||
|
*
|
||||||
|
* 4) For file schemes, if USE_DOS_PATH is set all '/'
|
||||||
|
* are converted to backslashes.
|
||||||
|
*
|
||||||
|
* 5) For file schemes, if USE_DOS_PATH isn't set all '\'
|
||||||
|
* are converted to forward slashes.
|
||||||
*/
|
*/
|
||||||
static BOOL canonicalize_path_opaque(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
|
static BOOL canonicalize_path_opaque(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr;
|
||||||
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
||||||
|
const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
|
||||||
|
|
||||||
if(!data->path) {
|
if(!data->path) {
|
||||||
uri->path_start = -1;
|
uri->path_start = -1;
|
||||||
@ -2846,11 +2866,36 @@ static BOOL canonicalize_path_opaque(const parse_data *data, Uri *uri, DWORD fla
|
|||||||
uri->canon_uri[uri->canon_len] = *ptr;
|
uri->canon_uri[uri->canon_len] = *ptr;
|
||||||
++uri->canon_len;
|
++uri->canon_len;
|
||||||
}
|
}
|
||||||
|
} else if(*ptr == '/' && is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = '\\';
|
||||||
|
++uri->canon_len;
|
||||||
|
} else if(*ptr == '\\' && is_file) {
|
||||||
|
if(!(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
|
/* Convert to a '/'. */
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = '/';
|
||||||
|
++uri->canon_len;
|
||||||
|
} else {
|
||||||
|
/* Just copy it over. */
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = *ptr;
|
||||||
|
++uri->canon_len;
|
||||||
|
}
|
||||||
} else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
|
} else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
|
||||||
!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS)) {
|
!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS)) {
|
||||||
|
if(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
|
/* Forbidden characters aren't percent encoded for file schemes
|
||||||
|
* with USE_DOS_PATH set.
|
||||||
|
*/
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = *ptr;
|
||||||
|
++uri->canon_len;
|
||||||
|
} else {
|
||||||
if(!computeOnly)
|
if(!computeOnly)
|
||||||
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
|
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
|
||||||
uri->canon_len += 3;
|
uri->canon_len += 3;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!computeOnly)
|
if(!computeOnly)
|
||||||
uri->canon_uri[uri->canon_len] = *ptr;
|
uri->canon_uri[uri->canon_len] = *ptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user