Commit aa122902 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

msvcrt: Implement _mbsncpy_s[_l]().

parent 3473dd52
...@@ -1157,8 +1157,8 @@ ...@@ -1157,8 +1157,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
......
...@@ -1514,8 +1514,8 @@ ...@@ -1514,8 +1514,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
......
...@@ -1525,8 +1525,8 @@ ...@@ -1525,8 +1525,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
......
...@@ -829,8 +829,8 @@ ...@@ -829,8 +829,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
......
...@@ -37,8 +37,48 @@ ...@@ -37,8 +37,48 @@
#define WX_TTY 0x40 #define WX_TTY 0x40
#define WX_TEXT 0x80 #define WX_TEXT 0x80
#define _MB_CP_SBCS 0
#define MSVCRT_FD_BLOCK_SIZE 32 #define MSVCRT_FD_BLOCK_SIZE 32
#define DEFINE_EXPECT(func) \
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
#define SET_EXPECT(func) \
expect_ ## func = TRUE
#define CHECK_EXPECT2(func) \
do { \
ok(expect_ ##func, "unexpected call " #func "\n"); \
called_ ## func = TRUE; \
}while(0)
#define CHECK_EXPECT(func) \
do { \
CHECK_EXPECT2(func); \
expect_ ## func = FALSE; \
}while(0)
#define CHECK_CALLED(func) \
do { \
ok(called_ ## func, "expected " #func "\n"); \
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT(invalid_parameter_handler);
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
const wchar_t *function, const wchar_t *file,
unsigned line, uintptr_t arg)
{
CHECK_EXPECT(invalid_parameter_handler);
ok(expression == NULL, "expression is not NULL\n");
ok(function == NULL, "function is not NULL\n");
ok(file == NULL, "file is not NULL\n");
ok(line == 0, "line = %u\n", line);
ok(arg == 0, "arg = %Ix\n", arg);
}
typedef struct typedef struct
{ {
HANDLE handle; HANDLE handle;
...@@ -57,6 +97,7 @@ typedef struct ...@@ -57,6 +97,7 @@ typedef struct
static ioinfo **__pioinfo; static ioinfo **__pioinfo;
static _invalid_parameter_handler (__cdecl *p__set_invalid_parameter_handler)(_invalid_parameter_handler);
static int (WINAPIV *p__open)(const char *, int, ...); static int (WINAPIV *p__open)(const char *, int, ...);
static int (__cdecl *p__close)(int); static int (__cdecl *p__close)(int);
static intptr_t (__cdecl *p__get_osfhandle)(int); static intptr_t (__cdecl *p__get_osfhandle)(int);
...@@ -65,6 +106,10 @@ static int (__cdecl *p_strncmp)(const char *, const char *, size_t); ...@@ -65,6 +106,10 @@ static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
static int (__cdecl *p_dupenv_s)(char **, size_t *, const char *); static int (__cdecl *p_dupenv_s)(char **, size_t *, const char *);
static int (__cdecl *p_wdupenv_s)(wchar_t **, size_t *, const wchar_t *); static int (__cdecl *p_wdupenv_s)(wchar_t **, size_t *, const wchar_t *);
static int* (__cdecl *p_errno)(void); static int* (__cdecl *p_errno)(void);
static errno_t (__cdecl *p__mbsncpy_s)(unsigned char*,size_t,const unsigned char*,size_t);
static int (__cdecl *p__ismbblead_l)(unsigned int,_locale_t);
static int (__cdecl *p__getmbcp)(void);
static int (__cdecl *p__setmbcp)(int);
/* make sure we use the correct errno */ /* make sure we use the correct errno */
#undef errno #undef errno
...@@ -83,6 +128,8 @@ static BOOL init(void) ...@@ -83,6 +128,8 @@ static BOOL init(void)
return FALSE; return FALSE;
} }
SET(p__set_invalid_parameter_handler, "_set_invalid_parameter_handler");
SET(__pioinfo, "__pioinfo"); SET(__pioinfo, "__pioinfo");
SET(p__open,"_open"); SET(p__open,"_open");
SET(p__close,"_close"); SET(p__close,"_close");
...@@ -93,7 +140,10 @@ static BOOL init(void) ...@@ -93,7 +140,10 @@ static BOOL init(void)
SET(p_dupenv_s, "_dupenv_s"); SET(p_dupenv_s, "_dupenv_s");
SET(p_wdupenv_s, "_wdupenv_s"); SET(p_wdupenv_s, "_wdupenv_s");
SET(p_errno, "_errno"); SET(p_errno, "_errno");
SET(p__mbsncpy_s, "_mbsncpy_s");
SET(p__ismbblead_l, "_ismbblead_l");
SET(p__getmbcp, "_getmbcp");
SET(p__setmbcp, "_setmbcp");
return TRUE; return TRUE;
} }
...@@ -222,13 +272,181 @@ static void test_wdupenv_s(void) ...@@ -222,13 +272,181 @@ static void test_wdupenv_s(void)
ok( !tmp, "_wdupenv_s returned pointer is %p\n", tmp ); ok( !tmp, "_wdupenv_s returned pointer is %p\n", tmp );
} }
#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, \
"Binary buffer mismatch - expected %s, got %s\n", \
debugstr_an(value, len), debugstr_an((char *)(buf), len)); }
static void test__mbsncpy_s(void)
{
unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5\x0";
unsigned char *mbstring2 = (unsigned char *)"\xb0\x0";
unsigned char buf[16];
errno_t err;
int oldcp;
oldcp = p__getmbcp();
if (p__setmbcp(936))
{
win_skip("Code page 936 is not available, skipping test.\n");
return;
}
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = p__mbsncpy_s(NULL, 0, mbstring, 0);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = p__mbsncpy_s(buf, 6, mbstring, 1);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\0\xcc", 4);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 6, mbstring, 2);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\xb2\xb3\0\xcc", 6);
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = p__mbsncpy_s(buf, 2, mbstring, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(err == STRUNCATE, "got %d.\n", err);
expect_bin(buf, "\x00\xb1\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 2, mbstring, 1);
ok(errno == err, "got %d.\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 2, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 1, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 0, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == EINVAL, "got %d.\n", err);
expect_bin(buf, "\xcc", 1);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 0, mbstring, 0);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == EINVAL, "got %d.\n", err);
expect_bin(buf, "\xcc", 1);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, -1, mbstring, 0);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, -1, mbstring, 256);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\xb2\xb3Q\xb4\xb5\x0\xcc", 9);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 1, mbstring2, 4);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 2, mbstring2, 4);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 1, mbstring2, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(err == STRUNCATE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 2, mbstring2, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\x0\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 1, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 2, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 3, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = p__mbsncpy_s(buf, 3, mbstring2, 2);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
p__setmbcp(oldcp);
}
START_TEST(msvcr80) START_TEST(msvcr80)
{ {
if(!init()) if(!init())
return; return;
ok(p__set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
test_ioinfo_flags(); test_ioinfo_flags();
test_strcmp(); test_strcmp();
test_dupenv_s(); test_dupenv_s();
test_wdupenv_s(); test_wdupenv_s();
test__mbsncpy_s();
} }
...@@ -807,8 +807,8 @@ ...@@ -807,8 +807,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
......
...@@ -900,6 +900,83 @@ unsigned char* CDECL _mbsncpy_l(unsigned char* dst, const unsigned char* src, si ...@@ -900,6 +900,83 @@ unsigned char* CDECL _mbsncpy_l(unsigned char* dst, const unsigned char* src, si
return ret; return ret;
} }
#if _MSVCR_VER>=80
errno_t CDECL _mbsncpy_s_l(unsigned char* dst, size_t maxsize, const unsigned char* src, size_t n, _locale_t locale)
{
BOOL truncate = (n == _TRUNCATE);
unsigned char *start = dst, *last;
pthreadmbcinfo mbcinfo;
unsigned int curlen;
if (!dst && !maxsize && !n)
return 0;
if (!MSVCRT_CHECK_PMT(dst != NULL)) return EINVAL;
if (!MSVCRT_CHECK_PMT(maxsize != 0)) return EINVAL;
if (!MSVCRT_CHECK_PMT(src != NULL))
{
*start = 0;
return EINVAL;
}
if (!n)
{
*start = 0;
return 0;
}
if (locale)
mbcinfo = locale->mbcinfo;
else
mbcinfo = get_mbcinfo();
curlen = 0;
last = dst;
while (*src && n && maxsize)
{
if (curlen)
{
--maxsize;
*dst++ = *src++;
if (!--curlen) --n;
continue;
}
last = dst;
if (!(mbcinfo->ismbcodepage && _ismbblead_l(*src, locale)))
{
curlen = 1;
continue;
}
curlen = 2;
if (!truncate && maxsize <= curlen) maxsize = 0;
}
if (!maxsize && truncate)
{
*last = 0;
return STRUNCATE;
}
if (!truncate && curlen && !src[curlen - 1])
{
*_errno() = EILSEQ;
*start = 0;
return EILSEQ;
}
if (!maxsize)
{
*start = 0;
if (!MSVCRT_CHECK_PMT_ERR(FALSE, ERANGE)) return ERANGE;
}
*dst = 0;
return 0;
}
errno_t CDECL _mbsncpy_s(unsigned char* dst, size_t maxsize, const unsigned char* src, size_t n)
{
return _mbsncpy_s_l(dst, maxsize, src, n, NULL);
}
#endif
/********************************************************************* /*********************************************************************
* _mbsncpy(MSVCRT.@) * _mbsncpy(MSVCRT.@)
* REMARKS * REMARKS
......
...@@ -651,6 +651,170 @@ static void test_strcmp(void) ...@@ -651,6 +651,170 @@ static void test_strcmp(void)
ok( ret == 0, "wrong ret %d\n", ret ); ok( ret == 0, "wrong ret %d\n", ret );
} }
#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, \
"Binary buffer mismatch - expected %s, got %s\n", \
debugstr_an(value, len), debugstr_an((char *)(buf), len)); }
static void test__mbsncpy_s(void)
{
unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5\x0";
unsigned char *mbstring2 = (unsigned char *)"\xb0\x0";
unsigned char buf[16];
errno_t err;
int oldcp;
oldcp = _getmbcp();
if (_setmbcp(936))
{
skip("Code page 936 is not available, skipping test.\n");
return;
}
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = _mbsncpy_s(NULL, 0, mbstring, 0);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = _mbsncpy_s(buf, 6, mbstring, 1);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\0\xcc", 4);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 6, mbstring, 2);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\xb2\xb3\0\xcc", 6);
errno = 0xdeadbeef;
memset(buf, 0xcc, sizeof(buf));
err = _mbsncpy_s(buf, 2, mbstring, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(err == STRUNCATE, "got %d.\n", err);
expect_bin(buf, "\x00\xb1\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 2, mbstring, 1);
ok(errno == err, "got %d.\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 2, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 1, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == ERANGE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 0, mbstring, 3);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == EINVAL, "got %d.\n", err);
expect_bin(buf, "\xcc", 1);
memset(buf, 0xcc, sizeof(buf));
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 0, mbstring, 0);
ok(errno == err, "got %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ok(err == EINVAL, "got %d.\n", err);
expect_bin(buf, "\xcc", 1);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, -1, mbstring, 0);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, -1, mbstring, 256);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\xb1\xb2\xb3Q\xb4\xb5\x0\xcc", 9);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 1, mbstring2, 4);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 2, mbstring2, 4);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 1, mbstring2, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(err == STRUNCATE, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 2, mbstring2, _TRUNCATE);
ok(errno == 0xdeadbeef, "got %d\n", errno);
ok(!err, "got %d.\n", err);
expect_bin(buf, "\xb0\x0\xcc", 3);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 1, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 2, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 3, mbstring2, 1);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
memset(buf, 0xcc, sizeof(buf));
errno = 0xdeadbeef;
err = _mbsncpy_s(buf, 3, mbstring2, 2);
ok(errno == err, "got %d\n", errno);
ok(err == EILSEQ, "got %d.\n", err);
expect_bin(buf, "\x0\xcc", 2);
_setmbcp(oldcp);
}
START_TEST(string) START_TEST(string)
{ {
ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL, ok(_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
...@@ -669,4 +833,5 @@ START_TEST(string) ...@@ -669,4 +833,5 @@ START_TEST(string)
test_SpecialCasing(); test_SpecialCasing();
test__mbbtype_l(); test__mbbtype_l();
test_strcmp(); test_strcmp();
test__mbsncpy_s();
} }
...@@ -673,8 +673,8 @@ ...@@ -673,8 +673,8 @@
@ stub _mbsncoll_l @ stub _mbsncoll_l
@ cdecl _mbsncpy(ptr str long) @ cdecl _mbsncpy(ptr str long)
@ cdecl _mbsncpy_l(ptr str long ptr) @ cdecl _mbsncpy_l(ptr str long ptr)
@ stub _mbsncpy_s @ cdecl _mbsncpy_s(ptr long str long)
@ stub _mbsncpy_s_l @ cdecl _mbsncpy_s_l(ptr long str long ptr)
@ cdecl _mbsnextc(str) @ cdecl _mbsnextc(str)
@ cdecl _mbsnextc_l(str ptr) @ cdecl _mbsnextc_l(str ptr)
@ cdecl _mbsnicmp(str str long) @ cdecl _mbsnicmp(str str long)
...@@ -1242,8 +1242,8 @@ ...@@ -1242,8 +1242,8 @@
@ stub _o__mbsncoll_l @ stub _o__mbsncoll_l
@ cdecl _o__mbsncpy(ptr str long) _mbsncpy @ cdecl _o__mbsncpy(ptr str long) _mbsncpy
@ cdecl _o__mbsncpy_l(ptr str long ptr) _mbsncpy_l @ cdecl _o__mbsncpy_l(ptr str long ptr) _mbsncpy_l
@ stub _o__mbsncpy_s @ cdecl _o__mbsncpy_s(ptr long str long) _mbsncpy_s
@ stub _o__mbsncpy_s_l @ cdecl _o__mbsncpy_s_l(ptr long str long ptr) _mbsncpy_s_l
@ cdecl _o__mbsnextc(str) _mbsnextc @ cdecl _o__mbsnextc(str) _mbsnextc
@ cdecl _o__mbsnextc_l(str ptr) _mbsnextc_l @ cdecl _o__mbsnextc_l(str ptr) _mbsnextc_l
@ cdecl _o__mbsnicmp(str str long) _mbsnicmp @ cdecl _o__mbsnicmp(str str long) _mbsnicmp
......
...@@ -93,6 +93,8 @@ _ACRTIMP size_t __cdecl _mbsnccnt(const unsigned char*,size_t); ...@@ -93,6 +93,8 @@ _ACRTIMP size_t __cdecl _mbsnccnt(const unsigned char*,size_t);
_ACRTIMP int __cdecl _mbsncmp(const unsigned char*,const unsigned char*,size_t); _ACRTIMP int __cdecl _mbsncmp(const unsigned char*,const unsigned char*,size_t);
_ACRTIMP int __cdecl _mbsncoll(const unsigned char*,const unsigned char*,size_t); _ACRTIMP int __cdecl _mbsncoll(const unsigned char*,const unsigned char*,size_t);
_ACRTIMP unsigned char* __cdecl _mbsncpy(unsigned char*,const unsigned char*,size_t); _ACRTIMP unsigned char* __cdecl _mbsncpy(unsigned char*,const unsigned char*,size_t);
_ACRTIMP errno_t __cdecl _mbsncpy_s(unsigned char*,size_t,const unsigned char*,size_t);
_ACRTIMP errno_t __cdecl _mbsncpy_s_l(unsigned char*,size_t,const unsigned char*,size_t,_locale_t);
_ACRTIMP unsigned int __cdecl _mbsnextc(const unsigned char*); _ACRTIMP unsigned int __cdecl _mbsnextc(const unsigned char*);
_ACRTIMP unsigned int __cdecl _mbsnextc_l(const unsigned char*,_locale_t); _ACRTIMP unsigned int __cdecl _mbsnextc_l(const unsigned char*,_locale_t);
_ACRTIMP int __cdecl _mbsnicmp(const unsigned char*,const unsigned char*,size_t); _ACRTIMP int __cdecl _mbsnicmp(const unsigned char*,const unsigned char*,size_t);
......
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