msvcrt: Add _mbscat_s_l implementation.
This commit is contained in:
parent
0eb112aa6e
commit
cf20731447
|
@ -1096,8 +1096,8 @@
|
||||||
@ stub _mblen_l
|
@ stub _mblen_l
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
@ stub _mbsbtype_l
|
@ stub _mbsbtype_l
|
||||||
@ stub _mbscat_s
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
@ stub _mbscat_s_l
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
@ stub _mbschr_l
|
@ stub _mbschr_l
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -1454,8 +1454,8 @@
|
||||||
@ stub _mblen_l
|
@ stub _mblen_l
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
@ stub _mbsbtype_l
|
@ stub _mbsbtype_l
|
||||||
@ stub _mbscat_s
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
@ stub _mbscat_s_l
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
@ stub _mbschr_l
|
@ stub _mbschr_l
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -1462,8 +1462,8 @@
|
||||||
@ stub _mblen_l
|
@ stub _mblen_l
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
@ stub _mbsbtype_l
|
@ stub _mbsbtype_l
|
||||||
@ stub _mbscat_s
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
@ stub _mbscat_s_l
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
@ stub _mbschr_l
|
@ stub _mbschr_l
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -769,8 +769,8 @@
|
||||||
@ stub _mblen_l
|
@ stub _mblen_l
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
@ stub _mbsbtype_l
|
@ stub _mbsbtype_l
|
||||||
@ stub _mbscat_s
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
@ stub _mbscat_s_l
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
@ stub _mbschr_l
|
@ stub _mbschr_l
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -746,8 +746,8 @@
|
||||||
@ stub _mblen_l
|
@ stub _mblen_l
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
@ stub _mbsbtype_l
|
@ stub _mbsbtype_l
|
||||||
@ stub _mbscat_s
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
@ stub _mbscat_s_l
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
@ stub _mbschr_l
|
@ stub _mbschr_l
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -1052,6 +1052,56 @@ unsigned char * CDECL _mbscat( unsigned char *dst, const unsigned char *src )
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _mbscat_s_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int CDECL _mbscat_s_l( unsigned char *dst, MSVCRT_size_t size,
|
||||||
|
const unsigned char *src, MSVCRT__locale_t locale )
|
||||||
|
{
|
||||||
|
MSVCRT_size_t i, j;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if(!MSVCRT_CHECK_PMT(dst != NULL)) return MSVCRT_EINVAL;
|
||||||
|
if(!MSVCRT_CHECK_PMT(src != NULL)) return MSVCRT_EINVAL;
|
||||||
|
|
||||||
|
for(i=0; i<size; i++)
|
||||||
|
if(!dst[i]) break;
|
||||||
|
if(i == size) {
|
||||||
|
MSVCRT_INVALID_PMT("dst is not NULL-terminated", MSVCRT_EINVAL);
|
||||||
|
if(size) dst[0] = 0;
|
||||||
|
return MSVCRT_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i && _ismbblead_l(dst[i-1], locale)) {
|
||||||
|
ret = MSVCRT_EILSEQ;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j=0; src[j] && i+j<size; j++)
|
||||||
|
dst[i+j] = src[j];
|
||||||
|
if(i+j == size) {
|
||||||
|
MSVCRT_INVALID_PMT("dst buffer is to small", MSVCRT_ERANGE);
|
||||||
|
dst[0] = 0;
|
||||||
|
return MSVCRT_ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(j && _ismbblead_l(src[j-1], locale)) {
|
||||||
|
ret = MSVCRT_EILSEQ;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[i+j] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _mbscat_s (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int CDECL _mbscat_s( unsigned char *dst, MSVCRT_size_t size, const unsigned char *src )
|
||||||
|
{
|
||||||
|
return _mbscat_s_l(dst, size, src, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _mbscpy (MSVCRT.@)
|
* _mbscpy (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1009,6 +1009,7 @@ int _setmbcp_l(int, LCID, MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN;
|
||||||
int __cdecl MSVCRT__write(int,const void*,unsigned int);
|
int __cdecl MSVCRT__write(int,const void*,unsigned int);
|
||||||
int __cdecl _getch(void);
|
int __cdecl _getch(void);
|
||||||
int __cdecl _ismbblead(unsigned int);
|
int __cdecl _ismbblead(unsigned int);
|
||||||
|
int __cdecl _ismbblead_l(unsigned int, MSVCRT__locale_t);
|
||||||
int __cdecl _ismbclegal(unsigned int c);
|
int __cdecl _ismbclegal(unsigned int c);
|
||||||
int __cdecl _ismbstrail(const unsigned char* start, const unsigned char* str);
|
int __cdecl _ismbstrail(const unsigned char* start, const unsigned char* str);
|
||||||
int __cdecl MSVCRT_mbtowc(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
|
int __cdecl MSVCRT_mbtowc(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
|
||||||
|
|
|
@ -713,8 +713,8 @@
|
||||||
@ cdecl _mbsbtype(str long)
|
@ cdecl _mbsbtype(str long)
|
||||||
# stub _mbsbtype_l(str long ptr)
|
# stub _mbsbtype_l(str long ptr)
|
||||||
@ cdecl _mbscat(str str)
|
@ cdecl _mbscat(str str)
|
||||||
# stub _mbscat_s(str long str)
|
@ cdecl _mbscat_s(ptr long str)
|
||||||
# stub _mbscat_s_l(str long str ptr)
|
@ cdecl _mbscat_s_l(ptr long str ptr)
|
||||||
@ cdecl _mbschr(str long)
|
@ cdecl _mbschr(str long)
|
||||||
# stub _mbschr_l(str long ptr)
|
# stub _mbschr_l(str long ptr)
|
||||||
@ cdecl _mbscmp(str str)
|
@ cdecl _mbscmp(str str)
|
||||||
|
|
|
@ -58,6 +58,7 @@ static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t);
|
||||||
static int* (__cdecl *pmemcmp)(void *, const void *, size_t n);
|
static int* (__cdecl *pmemcmp)(void *, const void *, size_t n);
|
||||||
static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src);
|
static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src);
|
||||||
static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src);
|
static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src);
|
||||||
|
static int (__cdecl *p_mbscat_s)(unsigned char *dst, size_t size, const unsigned char *src);
|
||||||
static int (__cdecl *p_mbsnbcat_s)(unsigned char *dst, size_t size, const unsigned char *src, size_t count);
|
static int (__cdecl *p_mbsnbcat_s)(unsigned char *dst, size_t size, const unsigned char *src, size_t count);
|
||||||
static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
|
static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
|
||||||
static int (__cdecl *p__mbscpy_s)(unsigned char*, size_t, const unsigned char*);
|
static int (__cdecl *p__mbscpy_s)(unsigned char*, size_t, const unsigned char*);
|
||||||
|
@ -732,6 +733,86 @@ static void test_strcat_s(void)
|
||||||
ok(ret == EINVAL, "strcat_s: Writing to a NULL string returned %d, expected EINVAL\n", ret);
|
ok(ret == EINVAL, "strcat_s: Writing to a NULL string returned %d, expected EINVAL\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test__mbscat_s(void)
|
||||||
|
{
|
||||||
|
unsigned char dst[8], src[4];
|
||||||
|
int err;
|
||||||
|
int prev_cp = _getmbcp();
|
||||||
|
|
||||||
|
if(!p_mbscat_s)
|
||||||
|
{
|
||||||
|
win_skip("_mbscat_s not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
src[0] = dst[0] = 0;
|
||||||
|
err = p_mbscat_s(NULL, sizeof(dst), src);
|
||||||
|
ok(err == EINVAL, "_mbscat_s returned %d\n", err);
|
||||||
|
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), NULL);
|
||||||
|
ok(err == EINVAL, "_mbscat_s returned %d\n", err);
|
||||||
|
|
||||||
|
dst[0] = 'a';
|
||||||
|
err = p_mbscat_s(dst, 1, src);
|
||||||
|
ok(err == EINVAL, "_mbscat_s returned %d\n", err);
|
||||||
|
|
||||||
|
memset(dst, 'a', sizeof(dst));
|
||||||
|
dst[6] = 0;
|
||||||
|
src[0] = 'b';
|
||||||
|
src[1] = 0;
|
||||||
|
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == 0, "_mbscat_s returned %d\n", err);
|
||||||
|
ok(!memcmp(dst, "aaaaaab", 8), "dst = %s\n", dst);
|
||||||
|
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == ERANGE, "_mbscat_s returned %d\n", err);
|
||||||
|
ok(!dst[0], "dst[0] = %c\n", dst[0]);
|
||||||
|
ok(dst[1] == 'a', "dst[1] = %c\n", dst[1]);
|
||||||
|
|
||||||
|
_setmbcp(932);
|
||||||
|
/* test invalid str in dst */
|
||||||
|
dst[0] = 0x81;
|
||||||
|
dst[1] = 0x81;
|
||||||
|
dst[2] = 0x52;
|
||||||
|
dst[3] = 0;
|
||||||
|
src[0] = 'a';
|
||||||
|
src[1] = 0;
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == 0, "_mbscat_s returned %d\n", err);
|
||||||
|
|
||||||
|
/* test invalid str in src */
|
||||||
|
dst[0] = 0;
|
||||||
|
src[0] = 0x81;
|
||||||
|
src[1] = 0x81;
|
||||||
|
src[2] = 0x52;
|
||||||
|
src[3] = 0;
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == 0, "_mbscat_s returned %d\n", err);
|
||||||
|
|
||||||
|
/* test dst with leading byte on the end of buffer */
|
||||||
|
dst[0] = 'a';
|
||||||
|
dst[1] = 0x81;
|
||||||
|
dst[2] = 0;
|
||||||
|
src[0] = 'R';
|
||||||
|
src[1] = 0;
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == EILSEQ, "_mbscat_s returned %d\n", err);
|
||||||
|
ok(!memcmp(dst, "aR", 3), "dst = %s\n", dst);
|
||||||
|
|
||||||
|
/* test src with leading byte on the end of buffer */
|
||||||
|
dst[0] = 'a';
|
||||||
|
dst[1] = 0;
|
||||||
|
src[0] = 'b';
|
||||||
|
src[1] = 0x81;
|
||||||
|
src[2] = 0;
|
||||||
|
err = p_mbscat_s(dst, sizeof(dst), src);
|
||||||
|
ok(err == EILSEQ, "_mbscat_s returned %d\n", err);
|
||||||
|
ok(!memcmp(dst, "ab", 3), "dst = %s\n", dst);
|
||||||
|
_setmbcp(prev_cp);
|
||||||
|
}
|
||||||
|
|
||||||
static void test__mbsnbcpy_s(void)
|
static void test__mbsnbcpy_s(void)
|
||||||
{
|
{
|
||||||
unsigned char dest[8];
|
unsigned char dest[8];
|
||||||
|
@ -2984,6 +3065,7 @@ START_TEST(string)
|
||||||
SET(p__mb_cur_max,"__mb_cur_max");
|
SET(p__mb_cur_max,"__mb_cur_max");
|
||||||
pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" );
|
pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" );
|
||||||
pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" );
|
pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" );
|
||||||
|
p_mbscat_s = (void*)GetProcAddress( hMsvcrt, "_mbscat_s" );
|
||||||
p_mbsnbcat_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcat_s" );
|
p_mbsnbcat_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcat_s" );
|
||||||
p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" );
|
p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" );
|
||||||
p__mbscpy_s = (void *)GetProcAddress( hMsvcrt,"_mbscpy_s" );
|
p__mbscpy_s = (void *)GetProcAddress( hMsvcrt,"_mbscpy_s" );
|
||||||
|
@ -3037,6 +3119,7 @@ START_TEST(string)
|
||||||
test_memcpy_s();
|
test_memcpy_s();
|
||||||
test_memmove_s();
|
test_memmove_s();
|
||||||
test_strcat_s();
|
test_strcat_s();
|
||||||
|
test__mbscat_s();
|
||||||
test__mbsnbcpy_s();
|
test__mbsnbcpy_s();
|
||||||
test__mbscpy_s();
|
test__mbscpy_s();
|
||||||
test_mbcjisjms();
|
test_mbcjisjms();
|
||||||
|
|
Loading…
Reference in New Issue