Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
aa122902
Commit
aa122902
authored
Apr 26, 2024
by
Paul Gofman
Committed by
Alexandre Julliard
May 01, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Implement _mbsncpy_s[_l]().
parent
3473dd52
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
477 additions
and
15 deletions
+477
-15
msvcr100.spec
dlls/msvcr100/msvcr100.spec
+2
-2
msvcr110.spec
dlls/msvcr110/msvcr110.spec
+2
-2
msvcr120.spec
dlls/msvcr120/msvcr120.spec
+2
-2
msvcr80.spec
dlls/msvcr80/msvcr80.spec
+2
-2
msvcr80.c
dlls/msvcr80/tests/msvcr80.c
+219
-1
msvcr90.spec
dlls/msvcr90/msvcr90.spec
+2
-2
mbcs.c
dlls/msvcrt/mbcs.c
+77
-0
string.c
dlls/ucrtbase/tests/string.c
+165
-0
ucrtbase.spec
dlls/ucrtbase/ucrtbase.spec
+4
-4
mbstring.h
include/msvcrt/mbstring.h
+2
-0
No files found.
dlls/msvcr100/msvcr100.spec
View file @
aa122902
...
@@ -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)
...
...
dlls/msvcr110/msvcr110.spec
View file @
aa122902
...
@@ -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)
...
...
dlls/msvcr120/msvcr120.spec
View file @
aa122902
...
@@ -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)
...
...
dlls/msvcr80/msvcr80.spec
View file @
aa122902
...
@@ -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)
...
...
dlls/msvcr80/tests/msvcr80.c
View file @
aa122902
...
@@ -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\xb3
Q
\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\xb3
Q
\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
();
}
}
dlls/msvcr90/msvcr90.spec
View file @
aa122902
...
@@ -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)
...
...
dlls/msvcrt/mbcs.c
View file @
aa122902
...
@@ -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
...
...
dlls/ucrtbase/tests/string.c
View file @
aa122902
...
@@ -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\xb3
Q
\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\xb3
Q
\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
();
}
}
dlls/ucrtbase/ucrtbase.spec
View file @
aa122902
...
@@ -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
...
...
include/msvcrt/mbstring.h
View file @
aa122902
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment