From: Damjan Jovanovic Subject: [PATCH] msxml3: all string passed to IXMLDOMDocument_load() need to be URL-unescaped Message-Id: Date: Wed, 4 Dec 2019 19:35:47 +0200 msxml3 allows URL escape sequences even for C:\ style paths. eg. C:\Program%20Files\... Signed-off-by: Damjan Jovanovic --- dlls/msxml3/bsc.c | 8 ++++++-- dlls/msxml3/tests/domdoc.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/dlls/msxml3/bsc.c b/dlls/msxml3/bsc.c index df4cf37346..0100eb09ab 100644 --- a/dlls/msxml3/bsc.c +++ b/dlls/msxml3/bsc.c @@ -244,16 +244,20 @@ static const struct IBindStatusCallbackVtbl bsc_vtbl = HRESULT create_uri(const WCHAR *url, IUri **uri) { + WCHAR unescapedUrl[INTERNET_MAX_URL_LENGTH]; WCHAR fileUrl[INTERNET_MAX_URL_LENGTH]; + DWORD size; TRACE("%s\n", debugstr_w(url)); - if (!PathIsURLW(url)) + size = ARRAY_SIZE(unescapedUrl); + UrlUnescapeW(url, unescapedUrl, &size, 0); + if (!PathIsURLW(unescapedUrl)) { WCHAR fullpath[MAX_PATH]; DWORD needed = ARRAY_SIZE(fileUrl); - if (!PathSearchAndQualifyW(url, fullpath, ARRAY_SIZE(fullpath))) + if (!PathSearchAndQualifyW(unescapedUrl, fullpath, ARRAY_SIZE(fullpath))) { WARN("can't find path\n"); return E_FAIL; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index c4337ab191..9f01261ad3 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10219,6 +10219,8 @@ static void test_load(void) VARIANT src; HRESULT hr; void* ptr; + int i, n; + char *percent_path; GetTempPathA(MAX_PATH, path); strcat(path, "winetest.xml"); @@ -10268,6 +10270,41 @@ static void test_load(void) ok(hr == S_OK, "got 0x%08x\n", hr); SysFreeString(bstr1); + /* Regular local path with some URL encoded characters. */ + strcpy(path2, path); + n = strlen(path2); + path2[n-1] = '%'; + path2[n] = '6'; + path2[n+1] = 'C'; + path2[n+2] = '\0'; /* C:\path\to\winetest.xm%6C */ + test_doc_load_from_path(doc, path2); + + /* Regular local path with all URL encoded characters. */ + percent_path = HeapAlloc(GetProcessHeap(), 0, 3*n + 1); + for (i = 0; i < n; i++) + { + static char hex_tab[] = "0123456789ABCDEF"; + percent_path[3*i] = '%'; + percent_path[3*i + 1] = hex_tab[path[i] >> 4]; + percent_path[3*i + 2] = hex_tab[path[i] & 0xF]; + } + percent_path[3*n] = '\0'; + test_doc_load_from_path(doc, percent_path); + HeapFree(GetProcessHeap(), 0, percent_path); + + /* A file with an actual % sequence in its filename won't work */ + GetTempPathA(MAX_PATH, path2); + strcat(path2, "wine%20test.xml"); + write_to_file(path2, win1252xml); + bstr1 = _bstr_(path2); + V_VT(&src) = VT_BSTR; + V_BSTR(&src) = bstr1; + hr = IXMLDOMDocument_load(doc, src, &b); + ok(hr == S_FALSE, "Document loading should have failed, %#x.\n", hr); + ok(b == VARIANT_FALSE, "got %d\n", b); + SysFreeString(bstr1); + DeleteFileA(path2); + DeleteFileA(path); /* load from existing path, no xml content */