vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / posix / glibc / iconv / gconv_simple.c
blob730264309b277425dd81f8ceb3cc971f76015039
1 /* Simple transformations functions.
2 Copyright (C) 1997-2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <errno.h>
22 #include <gconv.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <wchar.h>
27 #include <gconv_int.h>
29 #include <libroot/wchar_private.h>
31 #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
32 MinF, MaxF, MinT, MaxT) \
33 extern int Fct (struct __gconv_step *, struct __gconv_step_data *, \
34 __const unsigned char **, __const unsigned char *, \
35 unsigned char **, size_t *, int, int);
36 #include "gconv_builtin.h"
39 /* Convert from ISO 646-IRV to the internal (UCS4-like) format. */
40 #define DEFINE_INIT 0
41 #define DEFINE_FINI 0
42 #define MIN_NEEDED_FROM 1
43 #define MIN_NEEDED_TO 4
44 #define FROM_DIRECTION 1
45 #define FROM_LOOP ascii_internal_loop
46 #define TO_LOOP ascii_internal_loop /* This is not used. */
47 #define FUNCTION_NAME __gconv_transform_ascii_internal
48 #define ONE_DIRECTION 1
50 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
51 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
52 #define LOOPFCT FROM_LOOP
53 #define BODY \
54 { \
55 if (__builtin_expect(*inptr > '\x7f', 0)) { \
56 /* The value is too large. We don't try transliteration here since \
57 this is not an error because of the lack of possibilities to \
58 represent the result. This is a genuine bug in the input since \
59 ASCII does not allow such values. */ \
60 STANDARD_FROM_LOOP_ERR_HANDLER(1); \
61 } else { \
62 /* It's an one byte sequence. */ \
63 *((uint32_t*)outptr) = *inptr++; \
64 outptr += sizeof(uint32_t); \
65 } \
67 #define LOOP_NEED_FLAGS
68 #include <iconv/loop.c>
69 #include <iconv/skeleton.c>
72 /* Convert from the internal (UCS4-like) format to ISO 646-IRV. */
73 #define DEFINE_INIT 0
74 #define DEFINE_FINI 0
75 #define MIN_NEEDED_FROM 4
76 #define MIN_NEEDED_TO 1
77 #define FROM_DIRECTION 1
78 #define FROM_LOOP internal_ascii_loop
79 #define TO_LOOP internal_ascii_loop /* This is not used. */
80 #define FUNCTION_NAME __gconv_transform_internal_ascii
81 #define ONE_DIRECTION 1
83 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
84 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
85 #define LOOPFCT FROM_LOOP
86 #define BODY \
87 { \
88 if (__builtin_expect(*((const uint32_t*)inptr) > 0x7f, 0)) { \
89 UNICODE_TAG_HANDLER(*((const uint32_t*)inptr), 4); \
90 STANDARD_TO_LOOP_ERR_HANDLER(4); \
91 } else { \
92 /* It's an one byte sequence. */ \
93 *outptr++ = *((const uint32_t*)inptr); \
94 inptr += sizeof(uint32_t); \
95 } \
97 #define LOOP_NEED_FLAGS
98 #include <iconv/loop.c>
99 #include <iconv/skeleton.c>
102 /* Convert from multibyte to wchar_t format. */
103 #define DEFINE_INIT 0
104 #define DEFINE_FINI 0
105 #define MIN_NEEDED_FROM 1
106 #define MAX_NEEDED_FROM MB_LEN_MAX
107 #define MIN_NEEDED_TO 4
108 #define MAX_NEEDED_TO 4
109 #define FROM_DIRECTION 1
110 #define FROM_LOOP multibyte_wchar_loop
111 #define TO_LOOP multibyte_wchar_loop /* This is not used. */
112 #define FUNCTION_NAME __gconv_transform_multibyte_wchar
113 #define ONE_DIRECTION 1
115 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
116 #define MAX_NEEDED_INPUT MAX_NEEDED_FROM
117 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
118 #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
119 #define LOOPFCT FROM_LOOP
120 #define BODY \
122 size_t inLen = inend - inptr; \
123 mbstate_t *state = step_data->__statep; \
124 size_t result \
125 = __mbrtowc((wchar_t*)outptr, (const char*)inptr, inLen, state); \
126 if (result == (size_t)-1) { \
127 /* illegal character, skip it */ \
128 STANDARD_FROM_LOOP_ERR_HANDLER(1); \
129 } else if (result == (size_t)-2) { \
130 /* input too short, do nothing */ \
131 } else if (result == 0) { \
132 /* termination character found */ \
133 outptr += sizeof(wchar_t); \
134 ++inptr; \
135 } else { \
136 /* a character has been converted */ \
137 inptr += result; \
138 outptr += sizeof(wchar_t); \
141 #define LOOP_NEED_FLAGS
142 #include <iconv/loop.c>
143 #include <iconv/skeleton.c>
146 /* Convert from wchar_t to multibyte format. */
147 #define DEFINE_INIT 0
148 #define DEFINE_FINI 0
149 #define MIN_NEEDED_FROM 4
150 #define MAX_NEEDED_FROM 4
151 #define MIN_NEEDED_TO MB_LEN_MAX
152 #define MAX_NEEDED_TO MB_LEN_MAX
153 #define FROM_DIRECTION 1
154 #define FROM_LOOP wchar_multibyte_loop
155 #define TO_LOOP wchar_multibyte_loop /* This is not used. */
156 #define FUNCTION_NAME __gconv_transform_wchar_multibyte
157 #define ONE_DIRECTION 1
159 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
160 #define MAX_NEEDED_INPUT MAX_NEEDED_FROM
161 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
162 #define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
163 #define LOOPFCT FROM_LOOP
164 #define BODY \
166 mbstate_t *state = step_data->__statep; \
167 size_t result = __wcrtomb((char*)outptr, *(wchar_t*)inptr, state); \
168 if (result == (size_t)-1) { \
169 /* illegal character, skip it */ \
170 STANDARD_TO_LOOP_ERR_HANDLER(sizeof(wchar_t)); \
171 } else if (result == 0) { \
172 /* termination character found */ \
173 inptr += sizeof(wchar_t); \
174 ++outptr; \
175 } else { \
176 /* a character has been converted */ \
177 outptr += result; \
178 inptr += sizeof(wchar_t); \
181 #define LOOP_NEED_FLAGS
182 #include <iconv/loop.c>
183 #include <iconv/skeleton.c>