urlmon: Make canonicalize_path_hierarchical Uri object and parse_data struct independent.
This commit is contained in:
parent
24f4c4e14c
commit
29cdb35750
|
@ -2828,60 +2828,56 @@ static BOOL canonicalize_authority(const parse_data *data, Uri *uri, DWORD flags
|
||||||
* file:///c:/test%20test -> file:///c:/test%20test
|
* file:///c:/test%20test -> file:///c:/test%20test
|
||||||
* file:///c:/test%test -> file:///c:/test%25test
|
* file:///c:/test%test -> file:///c:/test%25test
|
||||||
*/
|
*/
|
||||||
static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
|
static DWORD canonicalize_path_hierarchical(const WCHAR *path, DWORD path_len, URL_SCHEME scheme_type, BOOL has_host, DWORD flags,
|
||||||
DWORD flags, BOOL computeOnly) {
|
WCHAR *ret_path) {
|
||||||
|
const BOOL known_scheme = scheme_type != URL_SCHEME_UNKNOWN;
|
||||||
|
const BOOL is_file = scheme_type == URL_SCHEME_FILE;
|
||||||
|
const BOOL is_res = scheme_type == URL_SCHEME_RES;
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr;
|
||||||
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
|
||||||
const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
|
|
||||||
const BOOL is_res = data->scheme_type == URL_SCHEME_RES;
|
|
||||||
|
|
||||||
BOOL escape_pct = FALSE;
|
BOOL escape_pct = FALSE;
|
||||||
|
DWORD len = 0;
|
||||||
|
|
||||||
if(!data->path) {
|
if(!path)
|
||||||
uri->path_start = -1;
|
return 0;
|
||||||
uri->path_len = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uri->path_start = uri->canon_len;
|
ptr = path;
|
||||||
ptr = data->path;
|
|
||||||
|
|
||||||
if(is_file && uri->host_start == -1) {
|
if(is_file && !has_host) {
|
||||||
/* Check if a '/' needs to be appended for the file scheme. */
|
/* Check if a '/' needs to be appended for the file scheme. */
|
||||||
if(data->path_len > 1 && is_drive_path(ptr) && !(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
if(path_len > 1 && is_drive_path(ptr) && !(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = '/';
|
ret_path[len] = '/';
|
||||||
uri->canon_len++;
|
len++;
|
||||||
escape_pct = TRUE;
|
escape_pct = TRUE;
|
||||||
} else if(*ptr == '/') {
|
} else if(*ptr == '/') {
|
||||||
if(!(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
if(!(flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
/* Copy the extra '/' over. */
|
/* Copy the extra '/' over. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = '/';
|
ret_path[len] = '/';
|
||||||
++uri->canon_len;
|
len++;
|
||||||
}
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_drive_path(ptr)) {
|
if(is_drive_path(ptr)) {
|
||||||
if(!computeOnly) {
|
if(ret_path) {
|
||||||
uri->canon_uri[uri->canon_len] = *ptr;
|
ret_path[len] = *ptr;
|
||||||
/* If there's a '|' after the drive letter, convert it to a ':'. */
|
/* If there's a '|' after the drive letter, convert it to a ':'. */
|
||||||
uri->canon_uri[uri->canon_len+1] = ':';
|
ret_path[len+1] = ':';
|
||||||
}
|
}
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
uri->canon_len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_file && *(data->path) && *(data->path) != '/') {
|
if(!is_file && *path && *path != '/') {
|
||||||
/* Prepend a '/' to the path if it doesn't have one. */
|
/* Prepend a '/' to the path if it doesn't have one. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = '/';
|
ret_path[len] = '/';
|
||||||
++uri->canon_len;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; ptr < data->path+data->path_len; ++ptr) {
|
for(; ptr < path+path_len; ++ptr) {
|
||||||
BOOL do_default_action = TRUE;
|
BOOL do_default_action = TRUE;
|
||||||
|
|
||||||
if(*ptr == '%' && !is_res) {
|
if(*ptr == '%' && !is_res) {
|
||||||
|
@ -2894,76 +2890,69 @@ static BOOL canonicalize_path_hierarchical(const parse_data *data, Uri *uri,
|
||||||
|
|
||||||
if(force_encode || escape_pct) {
|
if(force_encode || escape_pct) {
|
||||||
/* Escape the percent sign in the file URI. */
|
/* Escape the percent sign in the file URI. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
|
pct_encode_val(*ptr, ret_path+len);
|
||||||
uri->canon_len += 3;
|
len += 3;
|
||||||
do_default_action = FALSE;
|
do_default_action = FALSE;
|
||||||
} else if((is_unreserved(val) && known_scheme) ||
|
} else if((is_unreserved(val) && known_scheme) ||
|
||||||
(is_file && (is_unreserved(val) || is_reserved(val) ||
|
(is_file && (is_unreserved(val) || is_reserved(val) ||
|
||||||
(val && flags&Uri_CREATE_FILE_USE_DOS_PATH && !is_forbidden_dos_path_char(val))))) {
|
(val && flags&Uri_CREATE_FILE_USE_DOS_PATH && !is_forbidden_dos_path_char(val))))) {
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = val;
|
ret_path[len] = val;
|
||||||
++uri->canon_len;
|
len++;
|
||||||
|
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if(*ptr == '/' && is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
} else if(*ptr == '/' && is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) {
|
||||||
/* Convert the '/' back to a '\\'. */
|
/* Convert the '/' back to a '\\'. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = '\\';
|
ret_path[len] = '\\';
|
||||||
++uri->canon_len;
|
len++;
|
||||||
do_default_action = FALSE;
|
do_default_action = FALSE;
|
||||||
} else if(*ptr == '\\' && known_scheme) {
|
} else if(*ptr == '\\' && known_scheme) {
|
||||||
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
|
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
|
||||||
/* Convert '\\' into a '/'. */
|
/* Convert '\\' into a '/'. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = '/';
|
ret_path[len] = '/';
|
||||||
++uri->canon_len;
|
len++;
|
||||||
do_default_action = FALSE;
|
do_default_action = FALSE;
|
||||||
}
|
}
|
||||||
} else if(known_scheme && !is_res && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
|
} else if(known_scheme && !is_res && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
|
||||||
(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) || is_file)) {
|
(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) || is_file)) {
|
||||||
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
|
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH))) {
|
||||||
/* Escape the forbidden character. */
|
/* Escape the forbidden character. */
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
|
pct_encode_val(*ptr, ret_path+len);
|
||||||
uri->canon_len += 3;
|
len += 3;
|
||||||
do_default_action = FALSE;
|
do_default_action = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(do_default_action) {
|
if(do_default_action) {
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
uri->canon_uri[uri->canon_len] = *ptr;
|
ret_path[len] = *ptr;
|
||||||
++uri->canon_len;
|
len++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uri->path_len = uri->canon_len - uri->path_start;
|
|
||||||
|
|
||||||
/* Removing the dot segments only happens when it's not in
|
/* Removing the dot segments only happens when it's not in
|
||||||
* computeOnly mode and it's not a wildcard scheme. File schemes
|
* computeOnly mode and it's not a wildcard scheme. File schemes
|
||||||
* with USE_DOS_PATH set don't get dot segments removed.
|
* with USE_DOS_PATH set don't get dot segments removed.
|
||||||
*/
|
*/
|
||||||
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) &&
|
if(!(is_file && (flags & Uri_CREATE_FILE_USE_DOS_PATH)) &&
|
||||||
data->scheme_type != URL_SCHEME_WILDCARD) {
|
scheme_type != URL_SCHEME_WILDCARD) {
|
||||||
if(!(flags & Uri_CREATE_NO_CANONICALIZE) && !computeOnly) {
|
if(!(flags & Uri_CREATE_NO_CANONICALIZE) && ret_path) {
|
||||||
/* Remove the dot segments (if any) and reset everything to the new
|
/* Remove the dot segments (if any) and reset everything to the new
|
||||||
* correct length.
|
* correct length.
|
||||||
*/
|
*/
|
||||||
DWORD new_len = remove_dot_segments(uri->canon_uri+uri->path_start, uri->path_len);
|
len = remove_dot_segments(ret_path, len);
|
||||||
uri->canon_len -= uri->path_len-new_len;
|
|
||||||
uri->path_len = new_len;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!computeOnly)
|
if(ret_path)
|
||||||
TRACE("Canonicalized path %s len=%d\n",
|
TRACE("Canonicalized path %s len=%d\n", debugstr_wn(ret_path, len), len);
|
||||||
debugstr_wn(uri->canon_uri+uri->path_start, uri->path_len),
|
return len;
|
||||||
uri->path_len);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempts to canonicalize the path for an opaque URI.
|
/* Attempts to canonicalize the path for an opaque URI.
|
||||||
|
@ -3121,8 +3110,13 @@ static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags,
|
||||||
if(!canonicalize_path_opaque(data, uri, flags, computeOnly))
|
if(!canonicalize_path_opaque(data, uri, flags, computeOnly))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
if(!canonicalize_path_hierarchical(data, uri, flags, computeOnly))
|
if(!computeOnly)
|
||||||
return FALSE;
|
uri->path_start = uri->canon_len;
|
||||||
|
uri->path_len = canonicalize_path_hierarchical(data->path, data->path_len, data->scheme_type, data->host_len != 0,
|
||||||
|
flags, computeOnly ? NULL : uri->canon_uri+uri->canon_len);
|
||||||
|
uri->canon_len += uri->path_len;
|
||||||
|
if(!computeOnly && !uri->path_len)
|
||||||
|
uri->path_start = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Opaque URI's don't have an authority. */
|
/* Opaque URI's don't have an authority. */
|
||||||
|
|
Loading…
Reference in New Issue