Jacek Caban : itss: Canonicalize relative paths before resolving object.
Alexandre Julliard
julliard at winehq.org
Fri Sep 21 14:22:40 CDT 2012
Module: wine
Branch: master
Commit: 1a56a73c861f4e137119f1de86c41d0098fa2e40
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1a56a73c861f4e137119f1de86c41d0098fa2e40
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Sep 21 12:28:18 2012 +0200
itss: Canonicalize relative paths before resolving object.
---
dlls/itss/protocol.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
dlls/itss/tests/protocol.c | 3 ++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/dlls/itss/protocol.c b/dlls/itss/protocol.c
index fa2ad8b..6b188c6 100644
--- a/dlls/itss/protocol.c
+++ b/dlls/itss/protocol.c
@@ -134,6 +134,55 @@ static LPCWSTR skip_schema(LPCWSTR url)
return NULL;
}
+/* Adopted from urlmon */
+static void remove_dot_segments(WCHAR *path) {
+ const WCHAR *in = path;
+ WCHAR *out = path;
+
+ while(1) {
+ /* 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.
+ */
+ while(*in != '/') {
+ if(!(*out++ = *in++))
+ return;
+ }
+
+ *out++ = *in++;
+
+ while(*in) {
+ if(*in != '.')
+ break;
+
+ /* Handle ending "/." */
+ if(!in[1]) {
+ ++in;
+ break;
+ }
+
+ /* Handle "/./" */
+ if(in[1] == '/') {
+ in += 2;
+ continue;
+ }
+
+ /* If we don't have "/../" or ending "/.." */
+ if(in[1] != '.' || (in[2] && in[2] != '/'))
+ break;
+
+ in += *in ? 3 : 2;
+
+ /* Find the slash preceding out pointer and move out pointer to it */
+ if(out > path+1 && *--out == '/')
+ --out;
+ while(out > path && *(--out) != '/');
+ if(*out == '/')
+ ++out;
+ }
+ }
+}
+
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres)
{
IInternetProtocolSink_ReportResult(sink, hres, 0, NULL);
@@ -215,6 +264,8 @@ static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
*p = '/';
}
+ remove_dot_segments(object_name);
+
TRACE("Resolving %s\n", debugstr_w(object_name));
memset(&chm_object, 0, sizeof(chm_object));
diff --git a/dlls/itss/tests/protocol.c b/dlls/itss/tests/protocol.c
index b718502..7467d37 100644
--- a/dlls/itss/tests/protocol.c
+++ b/dlls/itss/tests/protocol.c
@@ -87,6 +87,8 @@ static const WCHAR blank_url7[] = {'m','k',':','@','M','S','I','T','S','t','o','
't','e','s','t','.','c','h','m',':',':','\\','b','l','a','n','k','.','h','t','m','l',0};
static const WCHAR blank_url8[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l','/',0};
+static const WCHAR blank_url9[] = {'i','t','s',':',
+ 't','e','s','t','.','c','h','m',':',':','/','d','i','r','/','.','.','/','b','l','a','n','k','.','h','t','m','l',0};
static enum {
ITS_PROTOCOL,
@@ -612,6 +614,7 @@ static void test_its_protocol(void)
test_protocol_url(factory, blank_url5, TRUE);
test_protocol_url(factory, blank_url6, TRUE);
test_protocol_url(factory, blank_url8, TRUE);
+ test_protocol_url(factory, blank_url9, TRUE);
bindf = BINDF_FROMURLMON | BINDF_NEEDFILE;
test_protocol_url(factory, blank_url1, TRUE);
}
More information about the wine-cvs
mailing list