mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
Add the wcslcpy, wcslcat functions
These functions are about to be added to POSIX, under Austin Group issue 986. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
This commit is contained in:
parent
454a20c875
commit
b54e5d1c92
@ -105,6 +105,8 @@ routines = \
|
||||
wcrtomb_chk \
|
||||
wcscat_chk \
|
||||
wcscpy_chk \
|
||||
wcslcat_chk \
|
||||
wcslcpy_chk \
|
||||
wcsncat_chk \
|
||||
wcsncpy_chk \
|
||||
wcsnrtombs_chk \
|
||||
|
@ -61,6 +61,8 @@ libc {
|
||||
GLIBC_2.38 {
|
||||
__strlcat_chk;
|
||||
__strlcpy_chk;
|
||||
__wcslcat_chk;
|
||||
__wcslcpy_chk;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
__fortify_fail;
|
||||
|
@ -782,6 +782,18 @@ do_test (void)
|
||||
wcsncpy (wbuf + 9, L"XABCDEFGH", 8);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcslcpy (wbuf + 7, L"X", 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcslcpy (wbuf + 7, L"X", l0 + 4);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcslcpy (wbuf + 9, L"XABCDEFGH", 8);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wcpncpy (wbuf + 9, L"XABCDEFGH", 8);
|
||||
CHK_FAIL_END
|
||||
@ -804,6 +816,11 @@ do_test (void)
|
||||
wcsncat (wbuf, L"ZYXWV", l0 + 3);
|
||||
CHK_FAIL_END
|
||||
|
||||
wmemcpy (wbuf, wstr1 + 4, 7);
|
||||
CHK_FAIL_START
|
||||
wcslcat (wbuf, L"ZYXWV", l0 + 11);
|
||||
CHK_FAIL_END
|
||||
|
||||
CHK_FAIL_START
|
||||
wmemcpy (wa.buf1 + 1, L"abcdefghij", 10);
|
||||
CHK_FAIL_END
|
||||
|
31
debug/wcslcat_chk.c
Normal file
31
debug/wcslcat_chk.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* Fortified version of wcslcat.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/* Check that the user-supplied size does not exceed the
|
||||
compiler-determined size, and then forward to wcslcat. */
|
||||
size_t
|
||||
__wcslcat_chk (wchar_t *__restrict s1, const wchar_t *__restrict s2,
|
||||
size_t n, size_t s1len)
|
||||
{
|
||||
if (__glibc_unlikely (s1len < n))
|
||||
__chk_fail ();
|
||||
|
||||
return __wcslcat (s1, s2, n);
|
||||
}
|
31
debug/wcslcpy_chk.c
Normal file
31
debug/wcslcpy_chk.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* Fortified version of wcslcpy.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/* Check that the user-supplied size does not exceed the
|
||||
compiler-determined size, and then forward to wcslcpy. */
|
||||
size_t
|
||||
__wcslcpy_chk (wchar_t *__restrict s1, const wchar_t *__restrict s2,
|
||||
size_t n, size_t s1len)
|
||||
{
|
||||
if (__glibc_unlikely (s1len < n))
|
||||
__chk_fail ();
|
||||
|
||||
return __wcslcpy (s1, s2, n);
|
||||
}
|
@ -203,6 +203,8 @@ extern size_t __wcslen (const wchar_t *__s) __attribute_pure__;
|
||||
extern size_t __wcsnlen (const wchar_t *__s, size_t __maxlen)
|
||||
__attribute_pure__;
|
||||
extern wchar_t *__wcscat (wchar_t *dest, const wchar_t *src);
|
||||
extern __typeof (wcslcat) __wcslcat;
|
||||
libc_hidden_proto (__wcslcat)
|
||||
extern wint_t __btowc (int __c) attribute_hidden;
|
||||
extern int __mbsinit (const __mbstate_t *__ps);
|
||||
extern size_t __mbrtowc (wchar_t *__restrict __pwc,
|
||||
@ -237,8 +239,11 @@ extern wchar_t *__wcscpy (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src)
|
||||
attribute_hidden __nonnull ((1, 2));
|
||||
libc_hidden_proto (__wcscpy)
|
||||
extern __typeof (wcslcpy) __wcslcpy;
|
||||
libc_hidden_proto (__wcslcpy)
|
||||
extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src, size_t __n);
|
||||
|
||||
extern wchar_t *__wcpcpy (wchar_t *__dest, const wchar_t *__src);
|
||||
extern wchar_t *__wcpncpy (wchar_t *__dest, const wchar_t *__src,
|
||||
size_t __n);
|
||||
|
@ -2328,8 +2328,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2667,5 +2667,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2776,8 +2776,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2428,5 +2428,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -548,8 +548,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _Exit F
|
||||
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
|
||||
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
|
||||
|
@ -545,8 +545,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _Exit F
|
||||
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
|
||||
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
|
||||
|
@ -2704,5 +2704,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2653,8 +2653,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2837,8 +2837,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2602,8 +2602,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2188,5 +2188,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -549,8 +549,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _Exit F
|
||||
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
|
||||
GLIBC_2.4 _IO_2_1_stdin_ D 0x98
|
||||
|
@ -2780,8 +2780,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2753,5 +2753,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2750,5 +2750,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2745,8 +2745,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2743,8 +2743,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2751,8 +2751,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2653,8 +2653,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2792,5 +2792,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2174,5 +2174,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2819,8 +2819,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2852,8 +2852,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2573,8 +2573,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2887,5 +2887,9 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2430,5 +2430,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2630,5 +2630,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -2817,8 +2817,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2610,8 +2610,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2660,8 +2660,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2657,8 +2657,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2812,8 +2812,12 @@ GLIBC_2.38 __nldbl___isoc23_vwscanf F
|
||||
GLIBC_2.38 __nldbl___isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 _IO_fprintf F
|
||||
GLIBC_2.4 _IO_printf F
|
||||
GLIBC_2.4 _IO_sprintf F
|
||||
|
@ -2625,8 +2625,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2576,8 +2576,12 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
GLIBC_2.4 __confstr_chk F
|
||||
GLIBC_2.4 __fgets_chk F
|
||||
GLIBC_2.4 __fgets_unlocked_chk F
|
||||
|
@ -2682,5 +2682,9 @@ GLIBC_2.38 __isoc23_wcstoumax F
|
||||
GLIBC_2.38 __isoc23_wscanf F
|
||||
GLIBC_2.38 __strlcat_chk F
|
||||
GLIBC_2.38 __strlcpy_chk F
|
||||
GLIBC_2.38 __wcslcat_chk F
|
||||
GLIBC_2.38 __wcslcpy_chk F
|
||||
GLIBC_2.38 strlcat F
|
||||
GLIBC_2.38 strlcpy F
|
||||
GLIBC_2.38 wcslcat F
|
||||
GLIBC_2.38 wcslcpy F
|
||||
|
@ -74,6 +74,8 @@ routines := \
|
||||
wcscpy \
|
||||
wcscspn \
|
||||
wcsdup \
|
||||
wcslcat \
|
||||
wcslcpy \
|
||||
wcslen \
|
||||
wcsmbsload \
|
||||
wcsncase \
|
||||
@ -155,6 +157,8 @@ tests := \
|
||||
tst-wchar-h \
|
||||
tst-wcpncpy \
|
||||
tst-wcrtomb \
|
||||
tst-wcslcat \
|
||||
tst-wcslcpy \
|
||||
tst-wcsnlen \
|
||||
tst-wcstod-nan-locale \
|
||||
tst-wcstod-nan-sign \
|
||||
|
@ -65,5 +65,7 @@ libc {
|
||||
__isoc23_vswscanf;
|
||||
__isoc23_vwscanf;
|
||||
__isoc23_wscanf;
|
||||
wcslcat;
|
||||
wcslcpy;
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +199,45 @@ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||
return __wcsncat_alias (__dest, __src, __n);
|
||||
}
|
||||
|
||||
#ifdef __USE_MISC
|
||||
extern size_t __wcslcpy_chk (wchar_t *__dest, const wchar_t *__src, size_t __n,
|
||||
size_t __destlen) __THROW;
|
||||
extern size_t __REDIRECT_NTH (__wcslcpy_alias,
|
||||
(wchar_t *__dest, const wchar_t *__src,
|
||||
size_t __n), wcslcpy);
|
||||
|
||||
__fortify_function size_t
|
||||
__NTH (wcslcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||
size_t __n))
|
||||
{
|
||||
if (__glibc_objsize (__dest) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__n
|
||||
> __glibc_objsize (__dest) / sizeof (wchar_t))
|
||||
|| __n > __glibc_objsize (__dest) / sizeof (wchar_t)))
|
||||
return __wcslcpy_chk (__dest, __src, __n,
|
||||
__glibc_objsize (__dest) / sizeof (wchar_t));
|
||||
return __wcslcpy_alias (__dest, __src, __n);
|
||||
}
|
||||
|
||||
extern size_t __wcslcat_chk (wchar_t *__dest, const wchar_t *__src, size_t __n,
|
||||
size_t __destlen) __THROW;
|
||||
extern size_t __REDIRECT_NTH (__wcslcat_alias,
|
||||
(wchar_t *__dest, const wchar_t *__src,
|
||||
size_t __n), wcslcat);
|
||||
|
||||
__fortify_function size_t
|
||||
__NTH (wcslcat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||
size_t __n))
|
||||
{
|
||||
if (__glibc_objsize (__dest) != (size_t) -1
|
||||
&& (!__builtin_constant_p (__n > __glibc_objsize (__dest)
|
||||
/ sizeof (wchar_t))
|
||||
|| __n > __glibc_objsize (__dest) / sizeof (wchar_t)))
|
||||
return __wcslcat_chk (__dest, __src, __n,
|
||||
__glibc_objsize (__dest) / sizeof (wchar_t));
|
||||
return __wcslcat_alias (__dest, __src, __n);
|
||||
}
|
||||
#endif /* __USE_MISC */
|
||||
|
||||
|
||||
extern int __REDIRECT_NTH_LDBL (__swprintf_alias,
|
||||
|
93
wcsmbs/tst-wcslcat.c
Normal file
93
wcsmbs/tst-wcslcat.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* Test the wcslcat function.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <array_length.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <support/check.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
struct {
|
||||
wchar_t buf1[16];
|
||||
wchar_t buf2[16];
|
||||
} s;
|
||||
|
||||
/* Nothing is written to the destination if its size is 0. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"", 0), 0);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"Hello!", 0), 6);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* No bytes are are modified in the target buffer if the source
|
||||
string is short enough. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
wcscpy (s.buf1, L"He");
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"llo!", array_length (s.buf1)), 6);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"Hello!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* A source string which fits exactly into the destination buffer is
|
||||
not truncated. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
wcscpy (s.buf1, L"H");
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"ello, world!!!", array_length (s.buf1)),
|
||||
15);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* A source string one character longer than the destination buffer
|
||||
is truncated by one character. The total length is returned. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
wcscpy (s.buf1, L"Hello");
|
||||
TEST_COMPARE (wcslcat (s.buf1, L", world!!!!", array_length (s.buf1)), 16);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* An even longer source string is truncated as well, and the total
|
||||
length is returned. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
wcscpy (s.buf1, L"Hello,");
|
||||
TEST_COMPARE (wcslcat (s.buf1, L" world!!!!!!!!", array_length (s.buf1)),
|
||||
20);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* A destination string which is not NUL-terminated does not result
|
||||
in any changes to the buffer. */
|
||||
wmemset (s.buf1, '$', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"", array_length (s.buf1)), 16);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@", 128);
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"Hello!", array_length (s.buf1)), 22);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@", 128);
|
||||
TEST_COMPARE (wcslcat (s.buf1, L"Hello, world!!!!!!!!",
|
||||
array_length (s.buf1)), 36);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"$$$$$$$$$$$$$$$$@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
78
wcsmbs/tst-wcslcpy.c
Normal file
78
wcsmbs/tst-wcslcpy.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* Test the wcslcpy function.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <array_length.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <support/check.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
struct {
|
||||
wchar_t buf1[16];
|
||||
wchar_t buf2[16];
|
||||
} s;
|
||||
|
||||
/* Nothing is written to the destination if its size is 0. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcpy (s.buf1, L"Hello!", 0), 6);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s), L"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* No bytes are are modified in the target buffer if the source
|
||||
string is short enough. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcpy (s.buf1, L"Hello!", array_length (s.buf1)), 6);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* A source string which fits exactly into the destination buffer is
|
||||
not truncated. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcpy (s.buf1, L"Hello, world!!!", array_length (s.buf1)),
|
||||
15);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* A source string one character longer than the destination buffer
|
||||
is truncated by one character. The untruncated source length is
|
||||
returned. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcpy (s.buf1, L"Hello, world!!!!", array_length (s.buf1)),
|
||||
16);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
/* An even longer source string is truncated as well, and the
|
||||
original length is returned. */
|
||||
wmemset (s.buf1, '@', array_length (s.buf1));
|
||||
wmemset (s.buf2, '@', array_length (s.buf2));
|
||||
TEST_COMPARE (wcslcpy (s.buf1, L"Hello, world!!!!!!!!",
|
||||
array_length (s.buf1)), 20);
|
||||
TEST_COMPARE_BLOB (&s, sizeof (s),
|
||||
L"Hello, world!!!\0@@@@@@@@@@@@@@@@@@@@@@@@@", 128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
@ -104,6 +104,19 @@ extern wchar_t *wcsncpy (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src, size_t __n)
|
||||
__THROW __nonnull ((1, 2));
|
||||
|
||||
#ifdef __USE_MISC
|
||||
/* Copy at most N - 1 characters from SRC to DEST. */
|
||||
extern size_t wcslcpy (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src, size_t __n)
|
||||
__THROW __nonnull ((1, 2)) __attr_access ((__write_only__, 1, 3));
|
||||
|
||||
/* Append SRC to DEST, possibly with truncation to keep the total size
|
||||
below N. */
|
||||
extern size_t wcslcat (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src, size_t __n)
|
||||
__THROW __nonnull ((1, 2)) __attr_access ((__read_write__, 1, 3));
|
||||
#endif
|
||||
|
||||
/* Append SRC onto DEST. */
|
||||
extern wchar_t *wcscat (wchar_t *__restrict __dest,
|
||||
const wchar_t *__restrict __src)
|
||||
|
60
wcsmbs/wcslcat.c
Normal file
60
wcsmbs/wcslcat.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Append a null-terminated wide string to another, with length checking.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
|
||||
size_t
|
||||
__wcslcat (wchar_t *__restrict dest, const wchar_t *__restrict src,
|
||||
size_t size)
|
||||
{
|
||||
size_t src_length = __wcslen (src);
|
||||
|
||||
/* Our implementation strlcat supports dest == NULL if size == 0
|
||||
(for consistency with snprintf and strlcpy), but wcsnlen does
|
||||
not, so we have to cover this case explicitly. */
|
||||
if (size == 0)
|
||||
return src_length;
|
||||
|
||||
size_t dest_length = __wcsnlen (dest, size);
|
||||
if (dest_length != size)
|
||||
{
|
||||
/* Copy at most the remaining number of characters in the
|
||||
destination buffer. Leave for the null terminator. */
|
||||
size_t to_copy = size - dest_length - 1;
|
||||
/* But not more than what is available in the source string. */
|
||||
if (to_copy > src_length)
|
||||
to_copy = src_length;
|
||||
|
||||
wchar_t *target = dest + dest_length;
|
||||
__wmemcpy (target, src, to_copy);
|
||||
target[to_copy] = '\0';
|
||||
}
|
||||
|
||||
/* If the sum wraps around, we have more than SIZE_MAX + 2 bytes in
|
||||
the two input strings (including both null terminators). If each
|
||||
byte in the address space can be assigned a unique size_t value
|
||||
(which the static_assert checks), then by the pigeonhole
|
||||
principle, the two input strings must overlap, which is
|
||||
undefined. */
|
||||
_Static_assert (sizeof (uintptr_t) == sizeof (size_t),
|
||||
"theoretical maximum object size covers address space");
|
||||
return dest_length + src_length;
|
||||
}
|
||||
libc_hidden_def (__wcslcat)
|
||||
weak_alias (__wcslcat, wcslcat)
|
46
wcsmbs/wcslcpy.c
Normal file
46
wcsmbs/wcslcpy.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copy a null-terminated wide string to a fixed-size buffer.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
size_t
|
||||
__wcslcpy (wchar_t *__restrict dest, const wchar_t *__restrict src, size_t size)
|
||||
{
|
||||
size_t src_length = __wcslen (src);
|
||||
|
||||
if (__glibc_unlikely (src_length >= size))
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
/* Copy the leading portion of the string. The last
|
||||
character is subsequently overwritten with the null
|
||||
terminator, but the destination size is usually a
|
||||
multiple of a small power of two, so writing it twice
|
||||
should be more efficient than copying an odd number of
|
||||
character. */
|
||||
__wmemcpy (dest, src, size);
|
||||
dest[size - 1] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Copy the string and its terminating null character. */
|
||||
__wmemcpy (dest, src, src_length + 1);
|
||||
return src_length;
|
||||
}
|
||||
libc_hidden_def (__wcslcpy)
|
||||
weak_alias (__wcslcpy, wcslcpy)
|
Loading…
Reference in New Issue
Block a user