msvcrt: Rework wcsncpy_s to work on overlapping pointers.

oldstable
Piotr Caban 2012-04-24 18:44:07 +02:00 committed by Alexandre Julliard
parent bdae6d7dc0
commit dc830aa640
2 changed files with 29 additions and 13 deletions

View File

@ -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)

View File

@ -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;
}
/******************************************************************