From 93b3ba76f6874cef44fbf4a8aa62afbe0b86b97f Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 18 Mar 2010 18:42:28 +0300 Subject: [PATCH] shlwapi: Fix StrCpyNW to deal with null inputs better, and don't use lstrcpynW. --- dlls/shlwapi/string.c | 30 ++++++++++++++++++++---------- dlls/shlwapi/tests/string.c | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c index cfb59ea4400..e00a92582e0 100644 --- a/dlls/shlwapi/string.c +++ b/dlls/shlwapi/string.c @@ -507,23 +507,33 @@ LPWSTR WINAPI StrCpyW(LPWSTR lpszStr, LPCWSTR lpszSrc) * Copy a string to another string, up to a maximum number of characters. * * PARAMS - * lpszStr [O] Destination string - * lpszSrc [I] Source string - * iLen [I] Maximum number of chars to copy + * dst [O] Destination string + * src [I] Source string + * count [I] Maximum number of chars to copy * * RETURNS - * lpszStr. + * dst. */ -LPWSTR WINAPI StrCpyNW(LPWSTR lpszStr, LPCWSTR lpszSrc, int iLen) +LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count) { - TRACE("(%p,%s,%i)\n", lpszStr, debugstr_w(lpszSrc), iLen); + LPWSTR d = dst; + LPCWSTR s = src; - lstrcpynW(lpszStr, lpszSrc, iLen); - return lpszStr; + TRACE("(%p,%s,%i)\n", dst, debugstr_w(src), count); + + if (s) + { + while ((count > 1) && *s) + { + count--; + *d++ = *s++; + } + } + if (count) *d = 0; + + return dst; } - - /************************************************************************* * SHLWAPI_StrStrHelperA * diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c index 00f0b023046..17c652de411 100644 --- a/dlls/shlwapi/tests/string.c +++ b/dlls/shlwapi/tests/string.c @@ -863,6 +863,33 @@ static void test_StrXXX_overflows(void) else win_skip("StrCatBuffA() is not available\n"); +if (0) +{ + /* crashes on XP */ + StrCpyNW(wbuf, (LPCWSTR)0x1, 10); + StrCpyNW((LPWSTR)0x1, wstr1, 10); +} + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, (LPCWSTR)0x1, 1), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], 0, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, 0, 10), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], 0, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, 0, 0), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + expect_eq(StrCpyNW(wbuf, wstr1, 0), wbuf, PWCHAR, "%p"); + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + memset(wbuf, 0xbf, sizeof(wbuf)); expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p"); expect_eq(wbuf[9], 0, WCHAR, "%x");