From 494910f3e8e051f56ebdb8caada75593c1473a3a Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Mon, 23 Nov 2015 17:34:24 -0800 Subject: [PATCH] shlwapi: implement URL_ESCAPE_AS_UTF8 Signed-off-by: Daniel Lehman --- dlls/shlwapi/tests/url.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ dlls/shlwapi/url.c | 37 +++++++++++++++++++++++++++++++------ include/shlwapi.h | 1 + 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c index 857ed15..c0d6598 100644 --- a/dlls/shlwapi/tests/url.c +++ b/dlls/shlwapi/tests/url.c @@ -302,6 +302,27 @@ static const TEST_URL_ESCAPE TEST_ESCAPE[] = { {"ftp\x1f\1end/", 0, 0, S_OK, "ftp%1F%01end/"} }; +typedef struct _TEST_URL_ESCAPEW { + const WCHAR url[INTERNET_MAX_URL_LENGTH]; + DWORD flags; + BOOL broken; + const WCHAR expecturl[INTERNET_MAX_URL_LENGTH]; +} TEST_URL_ESCAPEW; + +static const TEST_URL_ESCAPEW TEST_ESCAPEW[] = { + {{' ','<','>','"',0}, URL_ESCAPE_AS_UTF8, FALSE, {'%','2','0','%','3','C','%','3','E','%','2','2',0}}, + {{'{','}','|','\\',0}, URL_ESCAPE_AS_UTF8, FALSE, {'%','7','B','%','7','D','%','7','C','%','5','C',0}}, + {{'^',']','[','`',0}, URL_ESCAPE_AS_UTF8, FALSE, {'%','5','E','%','5','D','%','5','B','%','6','0',0}}, + {{'&','/','?','#',0}, URL_ESCAPE_AS_UTF8, FALSE, {'%','2','6','/','?','#',0}}, + {{'M','a','s','s',0}, URL_ESCAPE_AS_UTF8, FALSE, {'M','a','s','s',0}}, + {{'M','a','s','s',0}, URL_ESCAPE_AS_UTF8, FALSE, {'M','a','s','s',0}}, + + /* broken < Win7/Win2k8 */ + {{'M','a',0xdf,0}, URL_ESCAPE_AS_UTF8, TRUE, {'M','a','%','C','3','%','9','F',0}}, + {{0xdc00,0}, URL_ESCAPE_AS_UTF8, TRUE, {'%','E','F','%','B','F','%','B','D',0}}, + {{0xffff,0}, URL_ESCAPE_AS_UTF8, TRUE, {'%','E','F','%','B','F','%','B','F',0}} +}; + /* ################ */ typedef struct _TEST_URL_COMBINE { @@ -862,6 +883,15 @@ static void test_UrlEscapeA(void) ok(size == 34, "got %d, expected %d\n", size, 34); ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); + size = 1; + empty_string[0] = 127; + ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_AS_UTF8); + ok(ret == E_NOTIMPL || broken(ret == E_POINTER), /* < Win7/Win2k8 */ + "got %x, expected %x\n", ret, E_NOTIMPL); + ok(size == 1 || broken(size == 34), /* < Win7/Win2k8 */ + "got %d, expected %d\n", size, 1); + ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); + for(i=0; i= 0x80)) + return TRUE; + if (ch <= 31 || (ch >= 127 && ch <= 255) ) return TRUE; @@ -1069,7 +1074,7 @@ HRESULT WINAPI UrlEscapeW( LPCWSTR src; DWORD needed = 0, ret; BOOL stop_escaping = FALSE; - WCHAR next[5], *dst, *dst_ptr; + WCHAR next[16], *dst, *dst_ptr; INT len; PARSEDURLW parsed_url; DWORD int_flags; @@ -1085,7 +1090,8 @@ HRESULT WINAPI UrlEscapeW( if(dwFlags & ~(URL_ESCAPE_SPACES_ONLY | URL_ESCAPE_SEGMENT_ONLY | URL_DONT_ESCAPE_EXTRA_INFO | - URL_ESCAPE_PERCENT)) + URL_ESCAPE_PERCENT | + URL_ESCAPE_AS_UTF8)) FIXME("Unimplemented flags: %08x\n", dwFlags); dst_ptr = dst = HeapAlloc(GetProcessHeap(), 0, *pcchEscaped*sizeof(WCHAR)); @@ -1188,10 +1194,29 @@ HRESULT WINAPI UrlEscapeW( if(cur == '\\' && (int_flags & WINE_URL_BASH_AS_SLASH) && !stop_escaping) cur = '/'; if(URL_NeedEscapeW(cur, dwFlags, int_flags) && stop_escaping == FALSE) { - next[0] = '%'; - next[1] = hexDigits[(cur >> 4) & 0xf]; - next[2] = hexDigits[cur & 0xf]; - len = 3; + if(dwFlags & URL_ESCAPE_AS_UTF8) { + char utf[4]; + int i, ret; + ret = wine_utf8_wcstombs(WC_ERR_INVALID_CHARS, &cur, 1, utf, sizeof(utf)); + if(ret < 0) { + utf[0] = 0xef; + utf[1] = 0xbf; + utf[2] = 0xbd; + ret = 3; + } + len = 0; + for(i = 0; i < ret; i++) { + next[i*3+0] = '%'; + next[i*3+1] = hexDigits[(utf[i] >> 4) & 0xf]; + next[i*3+2] = hexDigits[utf[i] & 0xf]; + len += 3; + } + } else { + next[0] = '%'; + next[1] = hexDigits[(cur >> 4) & 0xf]; + next[2] = hexDigits[cur & 0xf]; + len = 3; + } } else { next[0] = cur; len = 1; diff --git a/include/shlwapi.h b/include/shlwapi.h index 205d5e6..e3b14b3 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -646,6 +646,7 @@ typedef enum { #define URL_UNESCAPE_INPLACE 0x00100000 #define URL_FILE_USE_PATHURL 0x00010000 +#define URL_ESCAPE_AS_UTF8 0x00040000 #define URL_ESCAPE_SEGMENT_ONLY 0x00002000 #define URL_ESCAPE_PERCENT 0x00001000 -- 1.9.5