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