character which has a multibyte representation which does not
fit. */
CHK_FAIL_START
- char smallbuf[2];
+ char smallbuf[1];
if (wcrtomb (smallbuf, L'\x100', &s) != 2)
FAIL ();
CHK_FAIL_END
+
+ /* Same input with a large enough buffer and we're good. */
+ char bigenoughbuf[2];
+ if (wcrtomb (bigenoughbuf, L'\x100', &s) != 2)
+ FAIL ();
#endif
wchar_t wenough[10];
/* Copyright (C) 2005-2022 Free Software Foundation, Inc.
+ Copyright The GNU Toolchain Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
size_t
__wcrtomb_chk (char *s, wchar_t wchar, mbstate_t *ps, size_t buflen)
{
- /* We do not have to implement the full wctomb semantics since we
- know that S cannot be NULL when we come here. */
- if (buflen < MB_CUR_MAX)
- __chk_fail ();
-
- return __wcrtomb (s, wchar, ps);
+ return __wcrtomb_internal (s, wchar, ps, buflen);
}
libc_hidden_proto (__mbrlen)
extern size_t __wcrtomb (char *__restrict __s, wchar_t __wc,
__mbstate_t *__restrict __ps) attribute_hidden;
+extern size_t __wcrtomb_internal (char *__restrict __s, wchar_t __wc,
+ __mbstate_t *__restrict __ps,
+ size_t __s_size)
+ attribute_hidden;
extern size_t __mbsrtowcs (wchar_t *__restrict __dst,
const char **__restrict __src,
size_t __len, __mbstate_t *__restrict __ps)
sequences.
One word about the interface of the function: there is no parameter
-specifying the length of the array @var{s}. Instead the function
-assumes that there are at least @code{MB_CUR_MAX} bytes available since
-this is the maximum length of any byte sequence representing a single
-character. So the caller has to make sure that there is enough space
-available, otherwise buffer overruns can occur.
+specifying the length of the array @var{s}, so the caller has to make sure
+that there is enough space available, otherwise buffer overruns can occur.
+This version of @theglibc{} does not assume that @var{s} is at least
+@var{MB_CUR_MAX} bytes long, but programs that need to run on @glibcadj{}
+versions that have this assumption documented in the manual must comply
+with this limit.
@pindex wchar.h
@code{wcrtomb} was introduced in @w{Amendment 1} to @w{ISO C90} and is
/* Copyright (C) 1996-2022 Free Software Foundation, Inc.
+ Copyright The GNU Toolchain Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
#include <errno.h>
#include <gconv.h>
#include <stdlib.h>
+#include <string.h>
#include <wchar.h>
#include <wcsmbsload.h>
static mbstate_t state;
size_t
-__wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
+__wcrtomb_internal (char *s, wchar_t wc, mbstate_t *ps, size_t s_size)
{
char buf[MB_LEN_MAX];
struct __gconv_step_data data;
/* A first special case is if S is NULL. This means put PS in the
initial state. */
if (s == NULL)
- {
- s = buf;
- wc = L'\0';
- }
+ wc = L'\0';
/* Tell where we want to have the result. */
- data.__outbuf = (unsigned char *) s;
- data.__outbufend = (unsigned char *) s + MB_CUR_MAX;
+ data.__outbuf = (unsigned char *) buf;
+ data.__outbufend = (unsigned char *) buf + sizeof buf;
/* Get the conversion functions. */
fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
if (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT
|| status == __GCONV_FULL_OUTPUT)
- result = data.__outbuf - (unsigned char *) s;
+ {
+ result = data.__outbuf - (unsigned char *) buf;
+
+ if (s != NULL)
+ {
+ if (result > s_size)
+ __chk_fail ();
+
+ memcpy (s, buf, result);
+ }
+ }
else
{
result = (size_t) -1;
return result;
}
+
+size_t
+__wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
+{
+ return __wcrtomb_internal (s, wc, ps, (size_t) -1);
+}
weak_alias (__wcrtomb, wcrtomb)
libc_hidden_weak (wcrtomb)