Jacek Caban : urlmon: Added backslash handling to remove_dot_segments.

Alexandre Julliard julliard at winehq.org
Fri Jan 21 11:08:21 CST 2011


Module: wine
Branch: master
Commit: 3c6c6e9d94ef52ce52f7f0feecb021b306a325cd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3c6c6e9d94ef52ce52f7f0feecb021b306a325cd

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jan 21 16:11:46 2011 +0100

urlmon: Added backslash handling to remove_dot_segments.

---

 dlls/urlmon/uri.c |   75 +++++++++++++++++++++++++++--------------------------
 1 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index 206fa6b..36ae913 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -350,6 +350,11 @@ static inline BOOL is_path_delim(WCHAR val) {
     return (!val || val == '#' || val == '?');
 }
 
+static inline BOOL is_slash(WCHAR c)
+{
+    return c == '/' || c == '\\';
+}
+
 static BOOL is_default_port(URL_SCHEME scheme, DWORD port) {
     DWORD i;
 
@@ -727,8 +732,6 @@ static void find_domain_name(const WCHAR *host, DWORD host_len,
 /* Removes the dot segments from a hierarchical URIs path component. This
  * function performs the removal in place.
  *
- * This is a modified version of Qt's QUrl function "removeDotsFromPath".
- *
  * This function returns the new length of the path string.
  */
 static DWORD remove_dot_segments(WCHAR *path, DWORD path_len) {
@@ -738,48 +741,46 @@ static DWORD remove_dot_segments(WCHAR *path, DWORD path_len) {
     DWORD len;
 
     while(in < end) {
-        /* A.  if the input buffer begins with a prefix of "/./" or "/.",
-         *     where "." is a complete path segment, then replace that
-         *     prefix with "/" in the input buffer; otherwise,
+        /* Move the first path segment in the input buffer to the end of
+         * the output buffer, and any subsequent characters up to, including
+         * the next "/" character (if any) or the end of the input buffer.
          */
-        if(in <= end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '/') {
-            in += 2;
-            continue;
-        } else if(in == end - 2 && in[0] == '/' && in[1] == '.') {
-            *out++ = '/';
-            in += 2;
+        while(in < end && !is_slash(*in))
+            *out++ = *in++;
+        if(in == end)
             break;
-        }
+        *out++ = *in++;
 
-        /* B.  if the input buffer begins with a prefix of "/../" or "/..",
-         *     where ".." is a complete path segment, then replace that
-         *     prefix with "/" in the input buffer and remove the last
-         *     segment and its preceding "/" (if any) from the output
-         *     buffer; otherwise,
-         */
-        if(in <= end - 4 && in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '/') {
-            while(out > path && *(--out) != '/');
+        while(in < end) {
+            if(*in != '.')
+                break;
 
-            in += 3;
-            continue;
-        } else if(in == end - 3 && in[0] == '/' && in[1] == '.' && in[2] == '.') {
-            while(out > path && *(--out) != '/');
+            /* Handle ending "/." */
+            if(in + 1 == end) {
+                ++in;
+                break;
+            }
 
-            if(*out == '/')
-                ++out;
+            /* Handle "/./" */
+            if(is_slash(in[1])) {
+                in += 2;
+                continue;
+            }
 
-            in += 3;
-            break;
-        }
+            /* If we don't have "/../" or ending "/.." */
+            if(in[1] != '.' || (in + 2 != end && !is_slash(in[2])))
+                break;
 
-        /* C.  move the first path segment in the input buffer to the end of
-         *     the output buffer, including the initial "/" character (if
-         *     any) and any subsequent characters up to, but not including,
-         *     the next "/" character or the end of the input buffer.
-         */
-        *out++ = *in++;
-        while(in < end && *in != '/')
-            *out++ = *in++;
+            /* Find the slash preceding out pointer and move out pointer to it */
+            if(out > path+1 && is_slash(*--out))
+                --out;
+            while(out > path && !is_slash(*(--out)));
+            if(is_slash(*out))
+                ++out;
+            in += 2;
+            if(in != end)
+                ++in;
+        }
     }
 
     len = out - path;




More information about the wine-cvs mailing list