Module: wine Branch: master Commit: dc830aa640f114bb6596d8bf23405be5d14df98b URL: http://source.winehq.org/git/wine.git/?a=commit;h=dc830aa640f114bb6596d8bf23...
Author: Piotr Caban piotr@codeweavers.com Date: Tue Apr 24 18:44:07 2012 +0200
msvcrt: Rework wcsncpy_s to work on overlapping pointers.
---
dlls/msvcrt/tests/string.c | 10 ++++++++++ dlls/msvcrt/wcs.c | 32 +++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index afa9954..6f36928 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -688,6 +688,16 @@ static void test_wcscpy_s(void) ok(ret == STRUNCATE, "expected STRUNCATE got %d\n", ret); ok(szDest[4] == 0, "szDest[4] not 0\n"); ok(!memcmp(szDest, szLongText, 4*sizeof(WCHAR)), "szDest = %s\n", wine_dbgstr_w(szDest)); + + ret = p_wcsncpy_s(NULL, 0, (void*)0xdeadbeef, 0); + ok(ret == 0, "ret = %d\n", ret); + + szDestShort[0] = '1'; + szDestShort[1] = 0; + ret = p_wcsncpy_s(szDestShort+1, 4, szDestShort, -1); + ok(ret == STRUNCATE, "expected ERROR_SUCCESS got %d\n", ret); + ok(szDestShort[0]=='1' && szDestShort[1]=='1' && szDestShort[2]=='1' && szDestShort[3]=='1', + "szDestShort = %s\n", wine_dbgstr_w(szDestShort)); }
static void test__wcsupr_s(void) diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 21cee47..e150a87 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -1229,34 +1229,40 @@ INT CDECL MSVCRT_wcscpy_s( MSVCRT_wchar_t* wcDest, MSVCRT_size_t numElement, con INT CDECL MSVCRT_wcsncpy_s( MSVCRT_wchar_t* wcDest, MSVCRT_size_t numElement, const MSVCRT_wchar_t *wcSrc, MSVCRT_size_t count ) { - MSVCRT_size_t size = 0; - INT ret = 0; + WCHAR *p = wcDest; + BOOL truncate = (count == MSVCRT__TRUNCATE); + + if(!wcDest && !numElement && !count) + return 0;
if (!wcDest || !numElement) return MSVCRT_EINVAL;
- wcDest[0] = 0; - if (!wcSrc) { + *wcDest = 0; return count ? MSVCRT_EINVAL : 0; }
- size = min(strlenW(wcSrc), count); - if (count==MSVCRT__TRUNCATE && size>=numElement) + while (numElement && count && *wcSrc) { - ret = MSVCRT_STRUNCATE; - size = numElement-1; + *p++ = *wcSrc++; + numElement--; + count--; } - else if (size >= numElement) + if (!numElement && truncate) { + *(p-1) = 0; + return MSVCRT_STRUNCATE; + } + else if (!numElement) + { + *wcDest = 0; return MSVCRT_ERANGE; }
- memcpy( wcDest, wcSrc, size*sizeof(WCHAR) ); - wcDest[size] = '\0'; - - return ret; + *p = 0; + return 0; }
/******************************************************************