vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / posix / wchar / wcrtomb.cpp
blob59f669eba0389884712e59cf5939e6d6ffb630dc
1 /*
2 ** Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>. All rights reserved.
3 ** Distributed under the terms of the Haiku License.
4 */
6 #include <errno.h>
7 #include <string.h>
8 #include <wchar.h>
10 #include <errno_private.h>
11 #include <LocaleBackend.h>
14 //#define TRACE_WCRTOMB
15 #ifdef TRACE_WCRTOMB
16 # include <OS.h>
17 # define TRACE(x) debug_printf x
18 #else
19 # define TRACE(x) ;
20 #endif
23 using BPrivate::Libroot::gLocaleBackend;
26 extern "C" size_t
27 __wcrtomb(char* s, wchar_t wc, mbstate_t* ps)
29 if (ps == NULL) {
30 static mbstate_t internalMbState;
31 ps = &internalMbState;
34 if (s == NULL)
35 wc = 0;
37 if (gLocaleBackend == NULL) {
39 * The POSIX locale is active. Since the POSIX locale only contains
40 * chars 0-127 and those ASCII chars are compatible with the UTF32
41 * values used in wint_t, we can just return the byte.
44 if (wc > 127) {
45 // char is non-ASCII
46 __set_errno(EILSEQ);
47 return (size_t)-1;
50 if (s != NULL)
51 *s = char(wc);
53 return 1;
56 size_t lengthUsed;
57 status_t status = gLocaleBackend->WcharToMultibyte(s, wc, ps, lengthUsed);
59 if (status == B_BAD_INDEX)
60 return (size_t)-2;
62 if (status == B_BAD_DATA) {
63 TRACE(("mbrtowc(): setting errno to EILSEQ\n"));
64 __set_errno(EILSEQ);
65 return (size_t)-1;
68 if (status != B_OK) {
69 TRACE(("wcrtomb(): setting errno to EINVAL (status: %lx)\n", status));
70 __set_errno(EINVAL);
71 return (size_t)-1;
74 return lengthUsed;
78 extern "C"
79 B_DEFINE_WEAK_ALIAS(__wcrtomb, wcrtomb);