Commit dfb846c2 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

shlwapi: Fixed error handling in StrRetToBufW.

parent dd99871c
...@@ -1523,6 +1523,9 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, ...@@ -1523,6 +1523,9 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest,
{ {
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 (!dest || !len)
return E_FAIL;
if (!src) if (!src)
{ {
WARN("Invalid lpStrRet would crash under Win32!\n"); WARN("Invalid lpStrRet would crash under Win32!\n");
...@@ -1531,17 +1534,24 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, ...@@ -1531,17 +1534,24 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest,
return E_FAIL; return E_FAIL;
} }
if (!dest || !len)
return E_FAIL;
*dest = '\0'; *dest = '\0';
switch (src->uType) switch (src->uType) {
{ case STRRET_WSTR: {
case STRRET_WSTR: size_t dst_len;
lstrcpynW(dest, src->u.pOleStr, 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); CoTaskMemFree(src->u.pOleStr);
if (len <= dst_len)
{
dest[0] = 0;
return E_NOT_SUFFICIENT_BUFFER;
}
break; break;
}
case STRRET_CSTR: case STRRET_CSTR:
if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len )) if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ))
...@@ -1561,6 +1571,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, ...@@ -1561,6 +1571,7 @@ HRESULT WINAPI StrRetToBufW (LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest,
FIXME("unknown type!\n"); FIXME("unknown type!\n");
return E_NOTIMPL; return E_NOTIMPL;
} }
return S_OK; return S_OK;
} }
......
...@@ -988,6 +988,7 @@ static void test_StrXXX_overflows(void) ...@@ -988,6 +988,7 @@ static void test_StrXXX_overflows(void)
WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH]; WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH];
const WCHAR fmt[] = {'%','s',0}; const WCHAR fmt[] = {'%','s',0};
STRRET strret; STRRET strret;
HRESULT hres;
int ret; int ret;
int i; int i;
...@@ -1059,9 +1060,27 @@ if (0) ...@@ -1059,9 +1060,27 @@ if (0)
memset(wbuf, 0xbf, sizeof(wbuf)); memset(wbuf, 0xbf, sizeof(wbuf));
strret.uType = STRRET_WSTR; strret.uType = STRRET_WSTR;
U(strret).pOleStr = StrDupW(wstr1); 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[9], 0, WCHAR, "%x");
expect_eq(wbuf[10], (WCHAR)0xbfbf, 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 else
win_skip("StrRetToBufW() is not available\n"); win_skip("StrRetToBufW() is not available\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment