shlwapi: Improved UrlCanonicalizeW implementation.

This commit is contained in:
Piotr Caban 2010-07-22 09:39:30 +02:00 committed by Alexandre Julliard
parent 20017183d3
commit b7c68573ae
2 changed files with 29 additions and 25 deletions

View File

@ -100,6 +100,8 @@ typedef struct _TEST_URL_CANONICALIZE {
static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
{"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/", TRUE},
{"http://www.winehq.org/..", 0, S_OK, "http://www.winehq.org/..", FALSE},
{"http://www.winehq.org/tests/tests2/../../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE},
{"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE},
{"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE},
{"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE},
@ -158,6 +160,8 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
{"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},
{"../A", 0, S_OK, "../A", FALSE},
{"A/../B", 0, S_OK, "B", TRUE},
{"/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"},
{"http://localhost/test.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/test.html"},

View File

@ -444,38 +444,38 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
*wk2++ = *wk1;
wk1++;
if (*wk1 == '.') {
while (*wk1 == '.') {
TRACE("found '/.'\n");
if (wk1[1] == '/' || wk1[1] == '\\') {
/* case of /./ -> skip the ./ */
wk1 += 2;
}
else if (wk1[1] == '.') {
/* found /.. look for next / */
TRACE("found '/..'\n");
if (wk1[2] == '/' || wk1[2] == '\\' ||wk1[2] == '?'
|| wk1[2] == '#' || !wk1[2]) {
/* case /../ -> need to backup wk2 */
TRACE("found '/../'\n");
*(wk2-1) = '\0'; /* set end of string */
mp = strrchrW(root, '/');
mp2 = strrchrW(root, '\\');
if(mp2 && (!mp || mp2 < mp))
mp = mp2;
if (mp && (mp >= root)) {
/* found valid backup point */
wk2 = mp + 1;
if(wk1[2] != '/' && wk1[2] != '\\')
wk1 += 2;
else
wk1 += 3;
}
else {
/* did not find point, restore '/' */
*(wk2-1) = slash;
}
else if (wk1[1] == '.' && (wk1[2] == '/'
|| wk1[2] == '\\' || wk1[2] == '?'
|| wk1[2] == '#' || !wk1[2])) {
/* case /../ -> need to backup wk2 */
TRACE("found '/../'\n");
*(wk2-1) = '\0'; /* set end of string */
mp = strrchrW(root, '/');
mp2 = strrchrW(root, '\\');
if(mp2 && (!mp || mp2 < mp))
mp = mp2;
if (mp && (mp >= root)) {
/* found valid backup point */
wk2 = mp + 1;
if(wk1[2] != '/' && wk1[2] != '\\')
wk1 += 2;
else
wk1 += 3;
}
else {
/* did not find point, restore '/' */
*(wk2-1) = slash;
break;
}
}
else
break;
}
}
*wk2 = '\0';