Jacek Caban : shlwapi: Fixed error handling in StrRetToBufW.
Alexandre Julliard
julliard at winehq.org
Thu Feb 23 16:27:51 CST 2017
Module: wine
Branch: master
Commit: dfb846c214a3073d743854e3f165b91dbfa7bec4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dfb846c214a3073d743854e3f165b91dbfa7bec4
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Feb 23 15:42:41 2017 +0100
shlwapi: Fixed error handling in StrRetToBufW.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/shlwapi/string.c | 79 ++++++++++++++++++++++++++-------------------
dlls/shlwapi/tests/string.c | 21 +++++++++++-
2 files changed, 65 insertions(+), 35 deletions(-)
diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c
index 8c4cb71..0b34d43 100644
--- a/dlls/shlwapi/string.c
+++ b/dlls/shlwapi/string.c
@@ -1521,47 +1521,58 @@ HRESULT WINAPI StrRetToBufA (LPSTRRET src, const ITEMIDLIST *pidl, LPSTR dest, U
*/
HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
{
- TRACE("dest=%p len=0x%x strret=%p pidl=%p\n", dest, len, src, pidl);
+ TRACE("dest=%p len=0x%x strret=%p pidl=%p\n", dest, len, src, pidl);
- if (!src)
- {
- WARN("Invalid lpStrRet would crash under Win32!\n");
- if (dest)
- *dest = '\0';
- return E_FAIL;
- }
+ if (!dest || !len)
+ return E_FAIL;
- if (!dest || !len)
- return E_FAIL;
+ if (!src)
+ {
+ WARN("Invalid lpStrRet would crash under Win32!\n");
+ if (dest)
+ *dest = '\0';
+ return E_FAIL;
+ }
- *dest = '\0';
+ *dest = '\0';
+
+ switch (src->uType) {
+ case STRRET_WSTR: {
+ size_t dst_len;
+ if (!src->u.pOleStr)
+ return E_FAIL;
+ dst_len = strlenW(src->u.pOleStr);
+ memcpy(dest, src->u.pOleStr, min(dst_len, len-1) * sizeof(WCHAR));
+ dest[min(dst_len, len-1)] = 0;
+ CoTaskMemFree(src->u.pOleStr);
+ if (len <= dst_len)
+ {
+ dest[0] = 0;
+ return E_NOT_SUFFICIENT_BUFFER;
+ }
+ break;
+ }
- switch (src->uType)
- {
- case STRRET_WSTR:
- lstrcpynW(dest, src->u.pOleStr, len);
- CoTaskMemFree(src->u.pOleStr);
- break;
+ case STRRET_CSTR:
+ if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ))
+ dest[len-1] = 0;
+ break;
- case STRRET_CSTR:
- if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ))
- dest[len-1] = 0;
- break;
+ case STRRET_OFFSET:
+ if (pidl)
+ {
+ if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
+ dest, len ))
+ dest[len-1] = 0;
+ }
+ break;
- case STRRET_OFFSET:
- if (pidl)
- {
- if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
- dest, len ))
- dest[len-1] = 0;
- }
- break;
+ default:
+ FIXME("unknown type!\n");
+ return E_NOTIMPL;
+ }
- default:
- FIXME("unknown type!\n");
- return E_NOTIMPL;
- }
- return S_OK;
+ return S_OK;
}
/*************************************************************************
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c
index ac14db0..f23ae3f 100644
--- a/dlls/shlwapi/tests/string.c
+++ b/dlls/shlwapi/tests/string.c
@@ -988,6 +988,7 @@ static void test_StrXXX_overflows(void)
WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH];
const WCHAR fmt[] = {'%','s',0};
STRRET strret;
+ HRESULT hres;
int ret;
int i;
@@ -1059,9 +1060,27 @@ if (0)
memset(wbuf, 0xbf, sizeof(wbuf));
strret.uType = STRRET_WSTR;
U(strret).pOleStr = StrDupW(wstr1);
- expect_eq2(pStrRetToBufW(&strret, NULL, wbuf, 10), S_OK, E_NOT_SUFFICIENT_BUFFER /* Vista */, HRESULT, "%x");
+ hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
+ ok(hres == E_NOT_SUFFICIENT_BUFFER || broken(hres == S_OK) /* winxp */,
+ "StrRetToBufW returned %08x\n", hres);
+ if (hres == E_NOT_SUFFICIENT_BUFFER)
+ expect_eq(wbuf[0], 0, WCHAR, "%x");
expect_eq(wbuf[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
+
+ memset(wbuf, 0xbf, sizeof(wbuf));
+ strret.uType = STRRET_CSTR;
+ StrCpyNA(U(strret).cStr, str1, MAX_PATH);
+ hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
+ ok(hres == S_OK, "StrRetToBufW returned %08x\n", hres);
+ ok(!memcmp(wbuf, wstr1, 9*sizeof(WCHAR)) && !wbuf[9], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
+
+ memset(wbuf, 0xbf, sizeof(wbuf));
+ strret.uType = STRRET_WSTR;
+ U(strret).pOleStr = NULL;
+ hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
+ ok(hres == E_FAIL, "StrRetToBufW returned %08x\n", hres);
+ ok(!wbuf[0], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
}
else
win_skip("StrRetToBufW() is not available\n");
More information about the wine-cvs
mailing list