Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
fdcf03fb
Commit
fdcf03fb
authored
Jun 27, 2022
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Unify the strncpy_s() and wcsncpy_s() implementations.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3514e65f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
42 deletions
+99
-42
string.c
dlls/msvcrt/string.c
+31
-25
string.c
dlls/msvcrt/tests/string.c
+51
-0
wcs.c
dlls/msvcrt/wcs.c
+17
-17
No files found.
dlls/msvcrt/string.c
View file @
fdcf03fb
...
...
@@ -1271,39 +1271,45 @@ char* __cdecl strncpy(char *dst, const char *src, size_t len)
/******************************************************************
* strncpy_s (MSVCRT.@)
*/
int
CDECL
strncpy_s
(
char
*
dest
,
size_t
numberOfElements
,
const
char
*
src
,
size_t
count
)
int
__cdecl
strncpy_s
(
char
*
dst
,
size_t
elem
,
const
char
*
src
,
size_t
count
)
{
size_t
i
,
end
;
char
*
p
=
dst
;
BOOL
truncate
=
(
count
==
_TRUNCATE
);
TRACE
(
"(%p %Iu %s %Iu)
\n
"
,
d
est
,
numberOfElements
,
debugstr_a
(
src
),
count
);
TRACE
(
"(%p %Iu %s %Iu)
\n
"
,
d
st
,
elem
,
debugstr_a
(
src
),
count
);
if
(
!
count
)
{
if
(
dest
&&
numberOfElements
)
*
de
st
=
0
;
if
(
!
count
)
{
if
(
dst
&&
elem
)
*
d
st
=
0
;
return
0
;
}
if
(
!
MSVCRT_CHECK_PMT
(
dest
!=
NULL
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
src
!=
NULL
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
numberOfElements
!=
0
))
return
EINVAL
;
if
(
count
!=
_TRUNCATE
&&
count
<
numberOfElements
)
end
=
count
;
else
end
=
numberOfElements
-
1
;
for
(
i
=
0
;
i
<
end
&&
src
[
i
];
i
++
)
dest
[
i
]
=
src
[
i
];
if
(
!
src
[
i
]
||
end
==
count
||
count
==
_TRUNCATE
)
{
dest
[
i
]
=
'\0'
;
return
0
;
if
(
!
MSVCRT_CHECK_PMT
(
dst
!=
NULL
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
elem
!=
0
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
src
!=
NULL
))
{
*
dst
=
0
;
return
EINVAL
;
}
MSVCRT_INVALID_PMT
(
"dest[numberOfElements] is too small"
,
EINVAL
);
dest
[
0
]
=
'\0'
;
return
EINVAL
;
while
(
elem
&&
count
&&
*
src
)
{
*
p
++
=
*
src
++
;
elem
--
;
count
--
;
}
if
(
!
elem
&&
truncate
)
{
*
(
p
-
1
)
=
0
;
return
STRUNCATE
;
}
else
if
(
!
elem
)
{
*
dst
=
0
;
return
ERANGE
;
}
*
p
=
0
;
return
0
;
}
/*********************************************************************
...
...
dlls/msvcrt/tests/string.c
View file @
fdcf03fb
...
...
@@ -64,6 +64,7 @@ static int (__cdecl *p_strncmp)(const char *, const char *, size_t);
static
int
(
__cdecl
*
p_strcpy
)(
char
*
dst
,
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
*
p_strncpy_s
)(
char
*
dst
,
size_t
size
,
const
char
*
src
,
size_t
count
);
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_mbsnbcpy_s
)(
unsigned
char
*
dst
,
size_t
size
,
const
unsigned
char
*
src
,
size_t
count
);
...
...
@@ -738,6 +739,55 @@ static void test_strcpy_s(void)
dest
[
4
]
==
'l'
&&
dest
[
5
]
==
'\0'
&&
dest
[
6
]
==
'\0'
&&
dest
[
7
]
==
'X'
,
"Unexpected return data from strcpy: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
\n
"
,
dest
[
0
],
dest
[
1
],
dest
[
2
],
dest
[
3
],
dest
[
4
],
dest
[
5
],
dest
[
6
],
dest
[
7
]);
if
(
!
p_strncpy_s
)
{
win_skip
(
"strncpy_s not found
\n
"
);
return
;
}
ret
=
p_strncpy_s
(
NULL
,
18
,
big
,
ARRAY_SIZE
(
big
));
ok
(
ret
==
EINVAL
,
"p_strncpy_s expect EINVAL got %d
\n
"
,
ret
);
dest
[
0
]
=
'A'
;
ret
=
p_strncpy_s
(
dest
,
8
,
NULL
,
1
);
ok
(
ret
==
EINVAL
,
"expected EINVAL got %d
\n
"
,
ret
);
ok
(
dest
[
0
]
==
0
,
"dest[0] not 0
\n
"
);
dest
[
0
]
=
'A'
;
ret
=
p_strncpy_s
(
dest
,
8
,
NULL
,
0
);
ok
(
ret
==
0
,
"expected ERROR_SUCCESS got %d
\n
"
,
ret
);
ok
(
dest
[
0
]
==
0
,
"dest[0] not 0
\n
"
);
dest
[
0
]
=
'A'
;
ret
=
p_strncpy_s
(
dest
,
0
,
big
,
ARRAY_SIZE
(
big
));
ok
(
ret
==
ERANGE
||
ret
==
EINVAL
,
"expected ERANGE/EINVAL got %d
\n
"
,
ret
);
ok
(
dest
[
0
]
==
0
||
ret
==
EINVAL
,
"dest[0] not 0
\n
"
);
ret
=
p_strncpy_s
(
dest
,
8
,
small
,
ARRAY_SIZE
(
small
));
ok
(
ret
==
0
,
"expected 0 got %d
\n
"
,
ret
);
ok
(
!
strcmp
(
dest
,
small
),
"dest != small
\n
"
);
dest
[
0
]
=
'A'
;
ret
=
p_strncpy_s
(
dest
,
8
,
big
,
ARRAY_SIZE
(
big
));
ok
(
ret
==
ERANGE
||
ret
==
EINVAL
,
"expected ERANGE/EINVAL got %d
\n
"
,
ret
);
ok
(
dest
[
0
]
==
0
,
"dest[0] not 0
\n
"
);
dest
[
0
]
=
'A'
;
ret
=
p_strncpy_s
(
dest
,
5
,
big
,
-
1
);
ok
(
ret
==
STRUNCATE
,
"expected STRUNCATE got %d
\n
"
,
ret
);
ok
(
dest
[
4
]
==
0
,
"dest[4] not 0
\n
"
);
ok
(
!
memcmp
(
dest
,
big
,
4
),
"dest = %s
\n
"
,
wine_dbgstr_a
(
dest
));
ret
=
p_strncpy_s
(
NULL
,
0
,
(
void
*
)
0xdeadbeef
,
0
);
ok
(
ret
==
0
,
"ret = %d
\n
"
,
ret
);
dest
[
0
]
=
'1'
;
dest
[
1
]
=
0
;
ret
=
p_strncpy_s
(
dest
+
1
,
4
,
dest
,
-
1
);
ok
(
ret
==
STRUNCATE
,
"expected ERROR_SUCCESS got %d
\n
"
,
ret
);
ok
(
dest
[
0
]
==
'1'
&&
dest
[
1
]
==
'1'
&&
dest
[
2
]
==
'1'
&&
dest
[
3
]
==
'1'
,
"dest = %s
\n
"
,
wine_dbgstr_a
(
dest
));
}
#define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \
...
...
@@ -4498,6 +4548,7 @@ START_TEST(string)
SET
(
p_strncmp
,
"strncmp"
);
pstrcpy_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"strcpy_s"
);
pstrcat_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"strcat_s"
);
p_strncpy_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"strncpy_s"
);
p_mbscat_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"_mbscat_s"
);
p_mbsnbcat_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"_mbsnbcat_s"
);
p_mbsnbcpy_s
=
(
void
*
)
GetProcAddress
(
hMsvcrt
,
"_mbsnbcpy_s"
);
...
...
dlls/msvcrt/wcs.c
View file @
fdcf03fb
...
...
@@ -2376,41 +2376,41 @@ wchar_t* __cdecl wcsncpy( wchar_t* s1, const wchar_t *s2, size_t n )
/******************************************************************
* wcsncpy_s (MSVCRT.@)
*/
INT
CDECL
wcsncpy_s
(
wchar_t
*
wcDest
,
size_t
numElement
,
const
wchar_t
*
wcSrc
,
size_t
count
)
INT
CDECL
wcsncpy_s
(
wchar_t
*
dst
,
size_t
elem
,
const
wchar_t
*
src
,
size_t
count
)
{
WCHAR
*
p
=
wcDe
st
;
WCHAR
*
p
=
d
st
;
BOOL
truncate
=
(
count
==
_TRUNCATE
);
if
(
!
wcDest
&&
!
numElement
&&
!
count
)
if
(
!
count
)
{
if
(
dst
&&
elem
)
*
dst
=
0
;
return
0
;
}
if
(
!
wcDest
||
!
numElement
)
return
EINVAL
;
if
(
!
wcSrc
)
if
(
!
MSVCRT_CHECK_PMT
(
dst
!=
NULL
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
elem
!=
0
))
return
EINVAL
;
if
(
!
MSVCRT_CHECK_PMT
(
src
!=
NULL
))
{
*
wcDe
st
=
0
;
return
count
?
EINVAL
:
0
;
*
d
st
=
0
;
return
EINVAL
;
}
while
(
numElement
&&
count
&&
*
wcS
rc
)
while
(
elem
&&
count
&&
*
s
rc
)
{
*
p
++
=
*
wcS
rc
++
;
numElement
--
;
*
p
++
=
*
s
rc
++
;
elem
--
;
count
--
;
}
if
(
!
numElement
&&
truncate
)
if
(
!
elem
&&
truncate
)
{
*
(
p
-
1
)
=
0
;
return
STRUNCATE
;
}
else
if
(
!
numElement
)
else
if
(
!
elem
)
{
*
wcDe
st
=
0
;
*
d
st
=
0
;
return
ERANGE
;
}
*
p
=
0
;
return
0
;
}
...
...
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