Module: wine Branch: master Commit: 3c6c6e9d94ef52ce52f7f0feecb021b306a325cd URL: http://source.winehq.org/git/wine.git/?a=commit;h=3c6c6e9d94ef52ce52f7f0feec...
Author: Jacek Caban jacek@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;