]> sourceware.org Git - glibc.git/blame - iconv/gconv_int.h
syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780)
[glibc.git] / iconv / gconv_int.h
CommitLineData
dff8da6b 1/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
e62c19f1 2 This file is part of the GNU C Library.
e62c19f1
UD
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
e62c19f1
UD
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
e62c19f1 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
e62c19f1
UD
17
18#ifndef _GCONV_INT_H
19#define _GCONV_INT_H 1
20
21#include "gconv.h"
c5738211 22#include <stdlib.h> /* For alloca used in macro below. */
6111babe
RM
23#include <ctype.h> /* For __toupper_l used in macro below. */
24#include <string.h> /* For strlen et al used in macro below. */
ec999b8e 25#include <libc-lock.h>
e62c19f1
UD
26
27__BEGIN_DECLS
28
5729e0e9
AZ
29/* We have to provide support for machines which are not able to handled
30 unaligned memory accesses. Some of the character encodings have
31 representations with a fixed width of 2 or 4 bytes. */
32#define get16(addr) \
33({ \
34 const struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr \
35 = (__typeof(__ptr))(addr); \
36 __ptr->r; \
37})
38#define get32(addr) \
39({ \
40 const struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr \
41 = (__typeof(__ptr))(addr); \
42 __ptr->r; \
43})
44
45#define put16(addr, val) \
46do { \
47 struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr \
48 = (__typeof(__ptr))(addr); \
49 __ptr->r = val; \
50} while (0)
51#define put32(addr, val) \
52do { \
53 struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr \
54 = (__typeof(__ptr))(addr); \
55 __ptr->r = val; \
56} while (0)
e62c19f1 57
9a321276 58/* Structure for alias definition. Simply two strings. */
e62c19f1
UD
59struct gconv_alias
60{
17427edd
UD
61 char *fromname;
62 char *toname;
e62c19f1
UD
63};
64
65
0d9f6793
UD
66/* Structure describing one loaded shared object. This normally are
67 objects to perform conversation but as a special case the db shared
68 object is also handled. */
d64b6ad0 69struct __gconv_loaded_object
0d9f6793 70{
b79f74cd 71 /* Name of the object. It must be the first structure element. */
0d9f6793
UD
72 const char *name;
73
74 /* Reference counter for the db functionality. If no conversion is
75 needed we unload the db library. */
76 int counter;
77
78 /* The handle for the shared object. */
b3fc5f84 79 void *handle;
0d9f6793
UD
80
81 /* Pointer to the functions the module defines. */
d64b6ad0
UD
82 __gconv_fct fct;
83 __gconv_init_fct init_fct;
84 __gconv_end_fct end_fct;
0d9f6793
UD
85};
86
87
e62c19f1
UD
88/* Description for an available conversion module. */
89struct gconv_module
90{
d2dfc5de 91 const char *from_string;
0d9f6793 92 const char *to_string;
e62c19f1 93
fab6d621
UD
94 int cost_hi;
95 int cost_lo;
e62c19f1 96
0d9f6793 97 const char *module_name;
2bd60880
UD
98
99 struct gconv_module *left; /* Prefix smaller. */
100 struct gconv_module *same; /* List of entries with identical prefix. */
2bd60880 101 struct gconv_module *right; /* Prefix larger. */
e62c19f1
UD
102};
103
104
91927b7c
AS
105/* The specification of the conversion that needs to be performed. */
106struct gconv_spec
107{
108 char *fromcode;
109 char *tocode;
110 bool translit;
111 bool ignore;
112};
113
c90a2db6
UD
114/* Flags for `gconv_open'. */
115enum
116{
117 GCONV_AVOID_NOCONV = 1 << 0
118};
119
7b503bcc
UD
120/* When GCONV_AVOID_NOCONV is set and no conversion is needed,
121 __GCONV_NULCONV should be returned. */
122enum
123{
124 __GCONV_NULCONV = -1
125};
c90a2db6 126
e62c19f1
UD
127/* Global variables. */
128
129/* Database of alias names. */
230491f0 130extern void *__gconv_alias_db attribute_hidden;
e62c19f1
UD
131
132/* Array with available modules. */
230491f0 133extern struct gconv_module *__gconv_modules_db attribute_hidden;
e62c19f1 134
6b98979f 135/* Value of the GCONV_PATH environment variable. */
aa32f798 136extern const char *__gconv_path_envvar attribute_hidden;
6b98979f 137
9e26f129 138/* Lock for the conversion database content. */
6f8a7dff 139__libc_lock_define (extern, __gconv_lock attribute_hidden)
9e26f129 140
e62c19f1 141
17c389fc
UD
142/* The gconv functions expects the name to be in upper case and complete,
143 including the trailing slashes if necessary. */
323fb88d 144#define norm_add_slashes(str,suffix) \
17c389fc
UD
145 ({ \
146 const char *cp = (str); \
147 char *result; \
148 char *tmp; \
149 size_t cnt = 0; \
db2f05ba 150 const size_t suffix_len = strlen (suffix); \
17c389fc
UD
151 \
152 while (*cp != '\0') \
153 if (*cp++ == '/') \
154 ++cnt; \
155 \
c5738211 156 tmp = result = __alloca (cp - (str) + 3 + suffix_len); \
17c389fc
UD
157 cp = (str); \
158 while (*cp != '\0') \
4b5b009c 159 *tmp++ = __toupper_l (*cp++, _nl_C_locobj_ptr); \
17c389fc
UD
160 if (cnt < 2) \
161 { \
162 *tmp++ = '/'; \
163 if (cnt < 1) \
323fb88d
UD
164 { \
165 *tmp++ = '/'; \
db2f05ba 166 if (suffix_len != 0) \
323fb88d
UD
167 tmp = __mempcpy (tmp, suffix, suffix_len); \
168 } \
17c389fc
UD
169 } \
170 *tmp = '\0'; \
171 result; \
172 })
173
174
f58a8c1c 175/* Return in *HANDLE, a descriptor for the transformation. The function expects
91927b7c
AS
176 the specification of the transformation in the structure pointed to by
177 CONV_SPEC. It only reads *CONV_SPEC and does not take ownership of it. */
178extern int __gconv_open (struct gconv_spec *conv_spec,
179 __gconv_t *handle, int flags);
180libc_hidden_proto (__gconv_open)
e62c19f1 181
7d4ec75e
AS
182/* This function accepts the charset names of the source and destination of the
183 conversion and populates *conv_spec with an equivalent conversion
184 specification that may later be used by __gconv_open. The charset names
185 might contain options in the form of suffixes that alter the conversion,
186 e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
187 and truncating any suffix options in fromcode, and processing and truncating
188 any suffix options in tocode. Supported suffix options ("TRANSLIT" or
189 "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
190 to be set to true. Unrecognized suffix options are silently discarded. If
191 the function succeeds, it returns conv_spec back to the caller. It returns
192 NULL upon failure. */
193extern struct gconv_spec *
194__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
195 const char *tocode);
196libc_hidden_proto (__gconv_create_spec)
197
198/* This function frees all heap memory allocated by __gconv_create_spec. */
199extern void
200__gconv_destroy_spec (struct gconv_spec *conv_spec);
201libc_hidden_proto (__gconv_destroy_spec)
202
e62c19f1 203/* Free resources associated with transformation descriptor CD. */
8bcdb7e0
L
204extern int __gconv_close (__gconv_t cd)
205 attribute_hidden;
e62c19f1
UD
206
207/* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF
208 according to rules described by CD and place up to *OUTBYTESLEFT
63e04088 209 bytes in buffer starting at *OUTBUF. Return number of non-identical
38677ace 210 conversions in *IRREVERSIBLE if this pointer is not null. */
55985355
UD
211extern int __gconv (__gconv_t cd, const unsigned char **inbuf,
212 const unsigned char *inbufend, unsigned char **outbuf,
8bcdb7e0
L
213 unsigned char *outbufend, size_t *irreversible)
214 attribute_hidden;
e62c19f1
UD
215
216/* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
217 the single steps necessary for transformation from FROMSET to TOSET. */
55985355
UD
218extern int __gconv_find_transform (const char *toset, const char *fromset,
219 struct __gconv_step **handle,
8bcdb7e0
L
220 size_t *nsteps, int flags)
221 attribute_hidden;
e62c19f1 222
6b98979f
UD
223/* Search for transformation in cache data. */
224extern int __gconv_lookup_cache (const char *toset, const char *fromset,
225 struct __gconv_step **handle, size_t *nsteps,
8bcdb7e0
L
226 int flags)
227 attribute_hidden;
6b98979f 228
9a018f6c
UD
229/* Compare the two name for whether they are after alias expansion the
230 same. This function uses the cache and fails if none is
231 loaded. */
232extern int __gconv_compare_alias_cache (const char *name1, const char *name2,
8bcdb7e0
L
233 int *result)
234 attribute_hidden;
9a018f6c 235
6b98979f 236/* Free data associated with a step's structure. */
8bcdb7e0
L
237extern void __gconv_release_step (struct __gconv_step *step)
238 attribute_hidden;
6b98979f 239
c5288d37
AS
240/* Read all the configuration data and cache it if not done so already. */
241extern void __gconv_load_conf (void) attribute_hidden;
e62c19f1 242
6b98979f 243/* Try to read module cache file. */
8bcdb7e0 244extern int __gconv_load_cache (void) attribute_hidden;
6b98979f 245
230491f0
UD
246/* Retrieve pointer to internal cache. */
247extern void *__gconv_get_cache (void);
248
249/* Retrieve pointer to internal module database. */
250extern struct gconv_module *__gconv_get_modules_db (void);
251
252/* Retrieve pointer to internal alias database. */
253extern void *__gconv_get_alias_db (void);
254
e62c19f1 255/* Comparison function to search alias. */
dff07c4b
UD
256extern int __gconv_alias_compare (const void *p1, const void *p2)
257 attribute_hidden;
e62c19f1
UD
258
259/* Clear reference to transformation step implementations which might
260 cause the code to be unloaded. */
55985355 261extern int __gconv_close_transform (struct __gconv_step *steps,
8bcdb7e0
L
262 size_t nsteps)
263 attribute_hidden;
e62c19f1 264
0db59742
UD
265/* Free all resources allocated for the transformation record when
266 using the cache. */
8bcdb7e0
L
267extern void __gconv_release_cache (struct __gconv_step *steps, size_t nsteps)
268 attribute_hidden;
0db59742 269
e62c19f1
UD
270/* Load shared object named by NAME. If already loaded increment reference
271 count. */
8bcdb7e0
L
272extern struct __gconv_loaded_object *__gconv_find_shlib (const char *name)
273 attribute_hidden;
e62c19f1
UD
274
275/* Release shared object. If no further reference is available unload
276 the object. */
8bcdb7e0
L
277extern void __gconv_release_shlib (struct __gconv_loaded_object *handle)
278 attribute_hidden;
e62c19f1
UD
279
280/* Fill STEP with information about builtin module with NAME. */
55985355 281extern void __gconv_get_builtin_trans (const char *name,
8bcdb7e0
L
282 struct __gconv_step *step)
283 attribute_hidden;
e62c19f1 284
7ac6fad9
FW
285/* Transliteration using the locale's data. */
286extern int __gconv_transliterate (struct __gconv_step *step,
287 struct __gconv_step_data *step_data,
288 const unsigned char *inbufstart,
289 const unsigned char **inbufp,
290 const unsigned char *inbufend,
291 unsigned char **outbufstart,
292 size_t *irreversible);
ba7b4d29 293libc_hidden_proto (__gconv_transliterate)
e62c19f1 294
dd9423a6 295/* If NAME is an codeset alias expand it. */
8bcdb7e0
L
296extern int __gconv_compare_alias (const char *name1, const char *name2)
297 attribute_hidden;
dd9423a6
UD
298
299
e62c19f1
UD
300/* Builtin transformations. */
301#ifdef _LIBC
f9ad060c 302# define __BUILTIN_TRANSFORM(Name) \
55985355
UD
303 extern int Name (struct __gconv_step *step, \
304 struct __gconv_step_data *data, \
305 const unsigned char **inbuf, \
f1d5c60d
UD
306 const unsigned char *inbufend, \
307 unsigned char **outbufstart, size_t *irreversible, \
308 int do_flush, int consume_incomplete)
e62c19f1 309
f9ad060c
UD
310__BUILTIN_TRANSFORM (__gconv_transform_ascii_internal);
311__BUILTIN_TRANSFORM (__gconv_transform_internal_ascii);
312__BUILTIN_TRANSFORM (__gconv_transform_utf8_internal);
313__BUILTIN_TRANSFORM (__gconv_transform_internal_utf8);
314__BUILTIN_TRANSFORM (__gconv_transform_ucs2_internal);
315__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2);
316__BUILTIN_TRANSFORM (__gconv_transform_ucs2reverse_internal);
317__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2reverse);
318__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4);
319__BUILTIN_TRANSFORM (__gconv_transform_ucs4_internal);
320__BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4le);
321__BUILTIN_TRANSFORM (__gconv_transform_ucs4le_internal);
322__BUILTIN_TRANSFORM (__gconv_transform_internal_utf16);
323__BUILTIN_TRANSFORM (__gconv_transform_utf16_internal);
324# undef __BUITLIN_TRANSFORM
325
326/* Specialized conversion function for a single byte to INTERNAL, recognizing
327 only ASCII characters. */
328extern wint_t __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c);
e62c19f1 329
e62c19f1
UD
330#endif
331
332__END_DECLS
333
334#endif /* gconv_int.h */
This page took 0.555788 seconds and 5 git commands to generate.