From 190645e5c58edbfb4baf59f97a6b537bfacf7644 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Thu, 21 Jan 2010 01:03:25 +0100 Subject: [PATCH] shlwapi: Improved res protocol handling in UrlCanonicalizeW. --- dlls/shlwapi/tests/url.c | 23 ++++++++++++++--------- dlls/shlwapi/url.c | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index ab3d0b6b273..b69ab0053cd 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -122,16 +122,22 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = { {"c:dir\\file", 0, S_OK, "file:///c:dir/file", FALSE}, {"c:\\tests\\foo bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, {"c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE}, + {"res://file", 0, S_OK, "res://file/", FALSE}, + {"res://file", URL_FILE_USE_PATHURL, S_OK, "res://file/", FALSE}, {"res:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests/foo bar", FALSE}, - {"res:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests\\foo bar", TRUE}, + {"res:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests\\foo bar", FALSE}, {"res:///c:/tests/foo%20bar", 0, S_OK, "res:///c:/tests/foo%20bar", FALSE}, - {"res:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c:/tests/foo%20bar", TRUE}, - {"res://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", TRUE}, - {"res://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", TRUE}, - {"res://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", TRUE}, - {"res:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c://tests/foo%20bar", TRUE}, - {"res:///c:\\tests\\foo bar", 0, S_OK, "res:///c:\\tests\\foo bar", TRUE}, - {"res:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "res:///c:\\tests\\foo bar", TRUE}, + {"res:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c:/tests/foo%20bar", FALSE}, + {"res://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, + {"res://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, + {"res://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, + {"res:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c://tests/foo%20bar", FALSE}, + {"res:///c:\\tests\\foo bar", 0, S_OK, "res:///c:\\tests\\foo bar", FALSE}, + {"res:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "res:///c:\\tests\\foo bar", FALSE}, + {"res://c:\\tests\\foo bar/res", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests\\foo bar/res", FALSE}, + {"res://c:\\tests/res\\foo%20bar/strange\\sth", 0, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE}, + {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE}, + {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_UNESCAPE, S_OK, "res://c:\\tests/res\\foo bar/strange\\sth", FALSE}, {"A", 0, S_OK, "A", FALSE}, {"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/, S_OK, "/uri-res/N2R?urn:sha1:B3K", FALSE} /*LimeWire online installer calls this*/, {"http:www.winehq.org/dir/../index.html", 0, S_OK, "http:www.winehq.org/index.html"}, @@ -1096,5 +1102,4 @@ START_TEST(url) test_UrlIs(); test_UrlUnescape(); test_ParseURL(); - } diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c index 544b5295023..d1b6e260992 100644 --- a/dlls/shlwapi/url.c +++ b/dlls/shlwapi/url.c @@ -283,6 +283,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, WCHAR slash = '/'; static const WCHAR wszFile[] = {'f','i','l','e',':'}; + static const WCHAR wszRes[] = {'r','e','s',':'}; static const WCHAR wszLocalhost[] = {'l','o','c','a','l','h','o','s','t'}; TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_w(pszUrl), pszCanonicalized, @@ -304,6 +305,11 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, && !memcmp(wszFile, pszUrl, sizeof(wszFile))) slash = '\\'; + if(nByteLen >= sizeof(wszRes) && !memcmp(wszRes, pszUrl, sizeof(wszRes))) { + dwFlags &= ~URL_FILE_USE_PATHURL; + slash = '\0'; + } + /* * state = * 0 initial 1,3 @@ -368,10 +374,12 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, wk1 += nWkLen; wk2 += nWkLen; - while(mp < wk2) { - if(*mp == '/' || *mp == '\\') - *mp = slash; - mp++; + if(slash) { + while(mp < wk2) { + if(*mp == '/' || *mp == '\\') + *mp = slash; + mp++; + } } break; case 4: @@ -380,13 +388,20 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, while(isalnumW(*wk1) || (*wk1 == '-') || (*wk1 == '.') || (*wk1 == ':')) *wk2++ = *wk1++; state = 5; - if (!*wk1) - *wk2++ = slash; + if (!*wk1) { + if(slash) + *wk2++ = slash; + else + *wk2++ = '/'; + } break; case 5: if (*wk1 != '/' && *wk1 != '\\') {state = 3; break;} while(*wk1 == '/' || *wk1 == '\\') { - *wk2++ = slash; + if(slash) + *wk2++ = slash; + else + *wk2++ = *wk1; wk1++; } state = 6; @@ -419,7 +434,10 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, wk2 += nLen; wk1 += nLen; } - *wk2++ = slash; + if(slash) + *wk2++ = slash; + else + *wk2++ = *wk1; wk1++; if (*wk1 == '.') { @@ -436,7 +454,10 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, /* case /../ -> need to backup wk2 */ TRACE("found '/../'\n"); *(wk2-1) = '\0'; /* set end of string */ - mp = strrchrW(root, slash); + mp = strrchrW(root, '/'); + mp2 = strrchrW(root, '\\'); + if(mp2 && (!mp || mp2 < mp)) + mp = mp2; if (mp && (mp >= root)) { /* found valid backup point */ wk2 = mp + 1;