shlwapi: Fix UrlCanonicalize.
- Added support for URL_FILE_USE_PATHURL. - Fix handling of '/' and '\'.
This commit is contained in:
parent
f989f62076
commit
bb8a7478bc
|
@ -60,10 +60,19 @@ const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
|
||||||
{"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
|
{"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
|
||||||
{"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example"},
|
{"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||||
{"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
|
{"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||||
|
{"http://www.winehq.org/tests\\../#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||||
|
{"http://www.winehq.org/tests/..\\#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||||
|
{"http://www.winehq.org\\tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||||
{"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
|
{"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
|
||||||
{"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar"},
|
{"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar"},
|
||||||
{"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
|
{"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
|
||||||
{"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
|
{"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
|
||||||
|
{"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
|
||||||
|
{"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
|
||||||
|
{"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
|
||||||
|
{"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
|
||||||
|
{"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
|
||||||
|
{"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar"}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _TEST_URL_ESCAPE {
|
typedef struct _TEST_URL_ESCAPE {
|
||||||
|
|
|
@ -327,9 +327,10 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
DWORD EscapeFlags;
|
DWORD EscapeFlags;
|
||||||
LPWSTR lpszUrlCpy, wk1, wk2, mp, root;
|
LPWSTR lpszUrlCpy, wk1, wk2, mp, mp2, root;
|
||||||
INT nByteLen, state;
|
INT nByteLen, state;
|
||||||
DWORD nLen, nWkLen;
|
DWORD nLen, nWkLen;
|
||||||
|
WCHAR slash = dwFlags & URL_FILE_USE_PATHURL ? '\\' : '/';
|
||||||
|
|
||||||
TRACE("(%s %p %p 0x%08lx)\n", debugstr_w(pszUrl), pszCanonicalized,
|
TRACE("(%s %p %p 0x%08lx)\n", debugstr_w(pszUrl), pszCanonicalized,
|
||||||
pcchCanonicalized, dwFlags);
|
pcchCanonicalized, dwFlags);
|
||||||
|
@ -376,23 +377,37 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||||
*wk2++ = *wk1++;
|
*wk2++ = *wk1++;
|
||||||
if (*wk1 != L'/') {state = 6; break;}
|
if (*wk1 != L'/') {state = 6; break;}
|
||||||
*wk2++ = *wk1++;
|
*wk2++ = *wk1++;
|
||||||
|
if((dwFlags & URL_FILE_USE_PATHURL) && *wk1 == '/')
|
||||||
|
wk1++;
|
||||||
state = 4;
|
state = 4;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
nWkLen = strlenW(wk1);
|
nWkLen = strlenW(wk1);
|
||||||
memcpy(wk2, wk1, (nWkLen + 1) * sizeof(WCHAR));
|
memcpy(wk2, wk1, (nWkLen + 1) * sizeof(WCHAR));
|
||||||
|
mp = wk2;
|
||||||
wk1 += nWkLen;
|
wk1 += nWkLen;
|
||||||
wk2 += nWkLen;
|
wk2 += nWkLen;
|
||||||
|
|
||||||
|
while(mp < wk2) {
|
||||||
|
if(*mp == '/' || *mp == '\\')
|
||||||
|
*mp = slash;
|
||||||
|
mp++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (!isalnumW(*wk1) && (*wk1 != L'-') && (*wk1 != L'.')) {state = 3; break;}
|
if (!isalnumW(*wk1) && (*wk1 != L'-') && (*wk1 != L'.') && (*wk1 != ':'))
|
||||||
while(isalnumW(*wk1) || (*wk1 == L'-') || (*wk1 == L'.')) *wk2++ = *wk1++;
|
{state = 3; break;}
|
||||||
state = 5;
|
while(isalnumW(*wk1) || (*wk1 == L'-') || (*wk1 == L'.') || (*wk1 == ':'))
|
||||||
break;
|
*wk2++ = *wk1++;
|
||||||
case 5:
|
state = 5;
|
||||||
if (*wk1 != L'/') {state = 3; break;}
|
break;
|
||||||
*wk2++ = *wk1++;
|
case 5:
|
||||||
state = 6;
|
if (*wk1 != '/' && *wk1 != '\\') {state = 3; break;}
|
||||||
|
while(*wk1 == '/') {
|
||||||
|
*wk2++ = slash;
|
||||||
|
wk1++;
|
||||||
|
}
|
||||||
|
state = 6;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
/* Now at root location, cannot back up any more. */
|
/* Now at root location, cannot back up any more. */
|
||||||
|
@ -400,7 +415,11 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||||
root = wk2-1;
|
root = wk2-1;
|
||||||
while (*wk1) {
|
while (*wk1) {
|
||||||
TRACE("wk1=%c\n", (CHAR)*wk1);
|
TRACE("wk1=%c\n", (CHAR)*wk1);
|
||||||
mp = strchrW(wk1, L'/');
|
|
||||||
|
mp = strchrW(wk1, '/');
|
||||||
|
mp2 = strchrW(wk1, '\\');
|
||||||
|
if(mp2 && mp2 < mp)
|
||||||
|
mp = mp2;
|
||||||
if (!mp) {
|
if (!mp) {
|
||||||
nWkLen = strlenW(wk1);
|
nWkLen = strlenW(wk1);
|
||||||
memcpy(wk2, wk1, (nWkLen + 1) * sizeof(WCHAR));
|
memcpy(wk2, wk1, (nWkLen + 1) * sizeof(WCHAR));
|
||||||
|
@ -408,35 +427,41 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||||
wk2 += nWkLen;
|
wk2 += nWkLen;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nLen = mp - wk1 + 1;
|
nLen = mp - wk1;
|
||||||
memcpy(wk2, wk1, nLen * sizeof(WCHAR));
|
if(nLen) {
|
||||||
wk2 += nLen;
|
memcpy(wk2, wk1, nLen * sizeof(WCHAR));
|
||||||
wk1 += nLen;
|
wk2 += nLen;
|
||||||
|
wk1 += nLen;
|
||||||
|
}
|
||||||
|
*wk2++ = slash;
|
||||||
|
wk1++;
|
||||||
|
|
||||||
if (*wk1 == L'.') {
|
if (*wk1 == L'.') {
|
||||||
TRACE("found '/.'\n");
|
TRACE("found '/.'\n");
|
||||||
if (*(wk1+1) == L'/') {
|
if (wk1[1] == '/' || wk1[1] == '\\') {
|
||||||
/* case of /./ -> skip the ./ */
|
/* case of /./ -> skip the ./ */
|
||||||
wk1 += 2;
|
wk1 += 2;
|
||||||
}
|
}
|
||||||
else if (*(wk1+1) == L'.') {
|
else if (wk1[1] == '.') {
|
||||||
/* found /.. look for next / */
|
/* found /.. look for next / */
|
||||||
TRACE("found '/..'\n");
|
TRACE("found '/..'\n");
|
||||||
if (*(wk1+2) == L'/' || *(wk1+2) == L'?' || *(wk1+2) == L'#' || *(wk1+2) == 0) {
|
if (wk1[2] == '/' || wk1[2] == '\\' ||wk1[2] == '?'
|
||||||
|
|| wk1[2] == '#' || !wk1[2]) {
|
||||||
/* case /../ -> need to backup wk2 */
|
/* case /../ -> need to backup wk2 */
|
||||||
TRACE("found '/../'\n");
|
TRACE("found '/../'\n");
|
||||||
*(wk2-1) = L'\0'; /* set end of string */
|
*(wk2-1) = L'\0'; /* set end of string */
|
||||||
mp = strrchrW(root, L'/');
|
mp = strrchrW(root, slash);
|
||||||
if (mp && (mp >= root)) {
|
if (mp && (mp >= root)) {
|
||||||
/* found valid backup point */
|
/* found valid backup point */
|
||||||
wk2 = mp + 1;
|
wk2 = mp + 1;
|
||||||
if(*(wk1+2) != L'/')
|
if(wk1[2] != '/' && wk1[2] != '\\')
|
||||||
wk1 += 2;
|
wk1 += 2;
|
||||||
else
|
else
|
||||||
wk1 += 3;
|
wk1 += 3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* did not find point, restore '/' */
|
/* did not find point, restore '/' */
|
||||||
*(wk2-1) = L'/';
|
*(wk2-1) = slash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -458,7 +483,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
|
||||||
while ((nLen > 0) && ((lpszUrlCpy[nLen-1] == '\r')||(lpszUrlCpy[nLen-1] == '\n')))
|
while ((nLen > 0) && ((lpszUrlCpy[nLen-1] == '\r')||(lpszUrlCpy[nLen-1] == '\n')))
|
||||||
lpszUrlCpy[--nLen]=0;
|
lpszUrlCpy[--nLen]=0;
|
||||||
|
|
||||||
if(dwFlags & URL_UNESCAPE)
|
if(dwFlags & (URL_UNESCAPE | URL_FILE_USE_PATHURL))
|
||||||
UrlUnescapeW(lpszUrlCpy, NULL, &nLen, URL_UNESCAPE_INPLACE);
|
UrlUnescapeW(lpszUrlCpy, NULL, &nLen, URL_UNESCAPE_INPLACE);
|
||||||
|
|
||||||
if((EscapeFlags = dwFlags & (URL_ESCAPE_UNSAFE |
|
if((EscapeFlags = dwFlags & (URL_ESCAPE_UNSAFE |
|
||||||
|
|
Loading…
Reference in New Issue