* Sync up to trunk head (r64377).
[reactos.git] / dll / win32 / urlmon / uri.c
index 052af22..6237df1 100644 (file)
@@ -340,8 +340,8 @@ static inline BOOL is_hexdigit(WCHAR val) {
             (val >= '0' && val <= '9'));
 }
 
-static inline BOOL is_path_delim(WCHAR val) {
-    return (!val || val == '#' || val == '?');
+static inline BOOL is_path_delim(URL_SCHEME scheme, WCHAR val) {
+    return (!val || (val == '#' && scheme != URL_SCHEME_FILE) || val == '?');
 }
 
 static inline BOOL is_slash(WCHAR c)
@@ -1834,7 +1834,7 @@ static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD f
     static const WCHAR slash[] = {'/',0};
     const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
 
-    if(is_path_delim(**ptr)) {
+    if(is_path_delim(data->scheme_type, **ptr)) {
         if(data->scheme_type == URL_SCHEME_WILDCARD && !data->must_have_path) {
             data->path = NULL;
             data->path_len = 0;
@@ -1844,7 +1844,7 @@ static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD f
             data->path_len = 1;
         }
     } else {
-        while(!is_path_delim(**ptr)) {
+        while(!is_path_delim(data->scheme_type, **ptr)) {
             if(**ptr == '%' && data->scheme_type != URL_SCHEME_UNKNOWN && !is_file) {
                 if(!check_pct_encoded(ptr)) {
                     *ptr = start;
@@ -1919,7 +1919,7 @@ static BOOL parse_path_opaque(const WCHAR **ptr, parse_data *data, DWORD flags)
     else
         data->path = *ptr;
 
-    while(!is_path_delim(**ptr)) {
+    while(!is_path_delim(data->scheme_type, **ptr)) {
         if(**ptr == '%' && known_scheme) {
             if(!check_pct_encoded(ptr)) {
                 *ptr = data->path;
@@ -2830,7 +2830,7 @@ static BOOL canonicalize_authority(const parse_data *data, Uri *uri, DWORD flags
  *      file:///c:/test%test    -> file:///c:/test%25test
  */
 static DWORD canonicalize_path_hierarchical(const WCHAR *path, DWORD path_len, URL_SCHEME scheme_type, BOOL has_host, DWORD flags,
-        WCHAR *ret_path) {
+        BOOL is_implicit_scheme, 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;
@@ -2896,7 +2896,7 @@ static DWORD canonicalize_path_hierarchical(const WCHAR *path, DWORD path_len, U
                 len += 3;
                 do_default_action = FALSE;
             } else if((is_unreserved(val) && known_scheme) ||
-                      (is_file && (is_unreserved(val) || is_reserved(val) ||
+                      (is_file && !is_implicit_scheme && (is_unreserved(val) || is_reserved(val) ||
                       (val && flags&Uri_CREATE_FILE_USE_DOS_PATH && !is_forbidden_dos_path_char(val))))) {
                 if(ret_path)
                     ret_path[len] = val;
@@ -2921,7 +2921,7 @@ static DWORD canonicalize_path_hierarchical(const WCHAR *path, DWORD path_len, U
             }
         } else if(known_scheme && !is_res && !is_unreserved(*ptr) && !is_reserved(*ptr) &&
                   (!(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. */
                 if(ret_path)
                     pct_encode_val(*ptr, ret_path+len);
@@ -3114,7 +3114,7 @@ static BOOL canonicalize_hierpart(const parse_data *data, Uri *uri, DWORD flags,
             if(!computeOnly)
                 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);
+                    flags, data->has_implicit_scheme, computeOnly ? NULL : uri->canon_uri+uri->canon_len);
             uri->canon_len += uri->path_len;
             if(!computeOnly && !uri->path_len)
                 uri->path_start = -1;
@@ -3881,8 +3881,8 @@ static HRESULT compare_file_paths(const Uri *a, const Uri *b, BOOL *ret)
         return S_OK;
     }
 
-    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, NULL);
-    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, NULL);
+    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, FALSE, NULL);
+    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, FALSE, NULL);
 
     canon_path_a = heap_alloc(len_a*sizeof(WCHAR));
     if(!canon_path_a)
@@ -3893,8 +3893,8 @@ static HRESULT compare_file_paths(const Uri *a, const Uri *b, BOOL *ret)
         return E_OUTOFMEMORY;
     }
 
-    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, canon_path_a);
-    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, canon_path_b);
+    len_a = canonicalize_path_hierarchical(a->canon_uri+a->path_start, a->path_len, a->scheme_type, FALSE, 0, FALSE, canon_path_a);
+    len_b = canonicalize_path_hierarchical(b->canon_uri+b->path_start, b->path_len, b->scheme_type, FALSE, 0, FALSE, canon_path_b);
 
     *ret = len_a == len_b && !memicmpW(canon_path_a, canon_path_b, len_a);