Deleted Added
full compact
rune.c (142582) rune.c (146261)
1/*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
39#endif /* LIBC_SCCS and not lint */
40#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
39#endif /* LIBC_SCCS and not lint */
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/lib/libc/locale/rune.c 142582 2005-02-26 21:47:54Z ru $");
41__FBSDID("$FreeBSD: head/lib/libc/locale/rune.c 146261 2005-05-16 09:32:41Z ru $");
42
43#include "namespace.h"
44#include <arpa/inet.h>
45#include <errno.h>
46#include <runetype.h>
42
43#include "namespace.h"
44#include <arpa/inet.h>
45#include <errno.h>
46#include <runetype.h>
47#include <runefile.h>
48#include <stdio.h>
49#include <string.h>
50#include <stdlib.h>
51#include <sys/types.h>
52#include <sys/stat.h>
53#include "un-namespace.h"
54
47#include <stdio.h>
48#include <string.h>
49#include <stdlib.h>
50#include <sys/types.h>
51#include <sys/stat.h>
52#include "un-namespace.h"
53
54#include "runefile.h"
55
55_RuneLocale *_Read_RuneMagi(FILE *);
56
57_RuneLocale *
58_Read_RuneMagi(FILE *fp)
59{
60 char *fdata, *data;
61 void *lastp;
62 _FileRuneLocale *frl;
63 _RuneLocale *rl;
64 _FileRuneEntry *frr;
65 _RuneEntry *rr;
66 struct stat sb;
67 int x, saverr;
68 void *variable;
69 _FileRuneEntry *runetype_ext_ranges;
70 _FileRuneEntry *maplower_ext_ranges;
71 _FileRuneEntry *mapupper_ext_ranges;
72 int runetype_ext_len = 0;
73
74 if (_fstat(fileno(fp), &sb) < 0)
75 return (NULL);
76
77 if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) {
78 errno = EFTYPE;
79 return (NULL);
80 }
81
82 if ((fdata = malloc(sb.st_size)) == NULL)
83 return (NULL);
84
85 errno = 0;
86 rewind(fp); /* Someone might have read the magic number once already */
87 if (errno) {
88 saverr = errno;
89 free(fdata);
90 errno = saverr;
91 return (NULL);
92 }
93
94 if (fread(fdata, sb.st_size, 1, fp) != 1) {
95 saverr = errno;
96 free(fdata);
97 errno = saverr;
98 return (NULL);
99 }
100
101 frl = (_FileRuneLocale *)fdata;
102 lastp = fdata + sb.st_size;
103
104 variable = frl + 1;
105
106 if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) {
107 free(fdata);
108 errno = EFTYPE;
109 return (NULL);
110 }
111
112 frl->variable_len = ntohl(frl->variable_len);
113 frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges);
114 frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges);
115 frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges);
116
117 for (x = 0; x < _CACHED_RUNES; ++x) {
118 frl->runetype[x] = ntohl(frl->runetype[x]);
119 frl->maplower[x] = ntohl(frl->maplower[x]);
120 frl->mapupper[x] = ntohl(frl->mapupper[x]);
121 }
122
123 runetype_ext_ranges = (_FileRuneEntry *)variable;
124 variable = runetype_ext_ranges + frl->runetype_ext_nranges;
125 if (variable > lastp) {
126 free(fdata);
127 errno = EFTYPE;
128 return (NULL);
129 }
130
131 maplower_ext_ranges = (_FileRuneEntry *)variable;
132 variable = maplower_ext_ranges + frl->maplower_ext_nranges;
133 if (variable > lastp) {
134 free(fdata);
135 errno = EFTYPE;
136 return (NULL);
137 }
138
139 mapupper_ext_ranges = (_FileRuneEntry *)variable;
140 variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
141 if (variable > lastp) {
142 free(fdata);
143 errno = EFTYPE;
144 return (NULL);
145 }
146
147 frr = runetype_ext_ranges;
148 for (x = 0; x < frl->runetype_ext_nranges; ++x) {
149 uint32_t *types;
150
151 frr[x].min = ntohl(frr[x].min);
152 frr[x].max = ntohl(frr[x].max);
153 frr[x].map = ntohl(frr[x].map);
154 if (frr[x].map == 0) {
155 int len = frr[x].max - frr[x].min + 1;
156 types = variable;
157 variable = types + len;
158 runetype_ext_len += len;
159 if (variable > lastp) {
160 free(fdata);
161 errno = EFTYPE;
162 return (NULL);
163 }
164 while (len-- > 0)
165 types[len] = ntohl(types[len]);
166 }
167 }
168
169 frr = maplower_ext_ranges;
170 for (x = 0; x < frl->maplower_ext_nranges; ++x) {
171 frr[x].min = ntohl(frr[x].min);
172 frr[x].max = ntohl(frr[x].max);
173 frr[x].map = ntohl(frr[x].map);
174 }
175
176 frr = mapupper_ext_ranges;
177 for (x = 0; x < frl->mapupper_ext_nranges; ++x) {
178 frr[x].min = ntohl(frr[x].min);
179 frr[x].max = ntohl(frr[x].max);
180 frr[x].map = ntohl(frr[x].map);
181 }
182 if ((char *)variable + frl->variable_len > (char *)lastp) {
183 free(fdata);
184 errno = EFTYPE;
185 return (NULL);
186 }
187
188 /*
189 * Convert from disk format to host format.
190 */
191 data = malloc(sizeof(_RuneLocale) +
192 (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
193 frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
194 runetype_ext_len * sizeof(*rr->__types) +
195 frl->variable_len);
196 if (data == NULL) {
197 saverr = errno;
198 free(fdata);
199 errno = saverr;
200 return (NULL);
201 }
202
203 rl = (_RuneLocale *)data;
204 rl->__variable = rl + 1;
205
206 memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
207 memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
208 rl->__invalid_rune = 0;
209
210 rl->__variable_len = frl->variable_len;
211 rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
212 rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
213 rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
214
215 for (x = 0; x < _CACHED_RUNES; ++x) {
216 rl->__runetype[x] = frl->runetype[x];
217 rl->__maplower[x] = frl->maplower[x];
218 rl->__mapupper[x] = frl->mapupper[x];
219 }
220
221 rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
222 rl->__variable = rl->__runetype_ext.__ranges +
223 rl->__runetype_ext.__nranges;
224
225 rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
226 rl->__variable = rl->__maplower_ext.__ranges +
227 rl->__maplower_ext.__nranges;
228
229 rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
230 rl->__variable = rl->__mapupper_ext.__ranges +
231 rl->__mapupper_ext.__nranges;
232
233 variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
234 frr = runetype_ext_ranges;
235 rr = rl->__runetype_ext.__ranges;
236 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
237 uint32_t *types;
238
239 rr[x].__min = frr[x].min;
240 rr[x].__max = frr[x].max;
241 rr[x].__map = frr[x].map;
242 if (rr[x].__map == 0) {
243 int len = rr[x].__max - rr[x].__min + 1;
244 types = variable;
245 variable = types + len;
246 rr[x].__types = rl->__variable;
247 rl->__variable = rr[x].__types + len;
248 while (len-- > 0)
249 rr[x].__types[len] = types[len];
250 } else
251 rr[x].__types = NULL;
252 }
253
254 frr = maplower_ext_ranges;
255 rr = rl->__maplower_ext.__ranges;
256 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
257 rr[x].__min = frr[x].min;
258 rr[x].__max = frr[x].max;
259 rr[x].__map = frr[x].map;
260 }
261
262 frr = mapupper_ext_ranges;
263 rr = rl->__mapupper_ext.__ranges;
264 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
265 rr[x].__min = frr[x].min;
266 rr[x].__max = frr[x].max;
267 rr[x].__map = frr[x].map;
268 }
269
270 memcpy(rl->__variable, variable, rl->__variable_len);
271 free(fdata);
272
273 /*
274 * Go out and zero pointers that should be zero.
275 */
276 if (!rl->__variable_len)
277 rl->__variable = NULL;
278
279 if (!rl->__runetype_ext.__nranges)
280 rl->__runetype_ext.__ranges = NULL;
281
282 if (!rl->__maplower_ext.__nranges)
283 rl->__maplower_ext.__ranges = NULL;
284
285 if (!rl->__mapupper_ext.__nranges)
286 rl->__mapupper_ext.__ranges = NULL;
287
288 return (rl);
289}
56_RuneLocale *_Read_RuneMagi(FILE *);
57
58_RuneLocale *
59_Read_RuneMagi(FILE *fp)
60{
61 char *fdata, *data;
62 void *lastp;
63 _FileRuneLocale *frl;
64 _RuneLocale *rl;
65 _FileRuneEntry *frr;
66 _RuneEntry *rr;
67 struct stat sb;
68 int x, saverr;
69 void *variable;
70 _FileRuneEntry *runetype_ext_ranges;
71 _FileRuneEntry *maplower_ext_ranges;
72 _FileRuneEntry *mapupper_ext_ranges;
73 int runetype_ext_len = 0;
74
75 if (_fstat(fileno(fp), &sb) < 0)
76 return (NULL);
77
78 if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) {
79 errno = EFTYPE;
80 return (NULL);
81 }
82
83 if ((fdata = malloc(sb.st_size)) == NULL)
84 return (NULL);
85
86 errno = 0;
87 rewind(fp); /* Someone might have read the magic number once already */
88 if (errno) {
89 saverr = errno;
90 free(fdata);
91 errno = saverr;
92 return (NULL);
93 }
94
95 if (fread(fdata, sb.st_size, 1, fp) != 1) {
96 saverr = errno;
97 free(fdata);
98 errno = saverr;
99 return (NULL);
100 }
101
102 frl = (_FileRuneLocale *)fdata;
103 lastp = fdata + sb.st_size;
104
105 variable = frl + 1;
106
107 if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) {
108 free(fdata);
109 errno = EFTYPE;
110 return (NULL);
111 }
112
113 frl->variable_len = ntohl(frl->variable_len);
114 frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges);
115 frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges);
116 frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges);
117
118 for (x = 0; x < _CACHED_RUNES; ++x) {
119 frl->runetype[x] = ntohl(frl->runetype[x]);
120 frl->maplower[x] = ntohl(frl->maplower[x]);
121 frl->mapupper[x] = ntohl(frl->mapupper[x]);
122 }
123
124 runetype_ext_ranges = (_FileRuneEntry *)variable;
125 variable = runetype_ext_ranges + frl->runetype_ext_nranges;
126 if (variable > lastp) {
127 free(fdata);
128 errno = EFTYPE;
129 return (NULL);
130 }
131
132 maplower_ext_ranges = (_FileRuneEntry *)variable;
133 variable = maplower_ext_ranges + frl->maplower_ext_nranges;
134 if (variable > lastp) {
135 free(fdata);
136 errno = EFTYPE;
137 return (NULL);
138 }
139
140 mapupper_ext_ranges = (_FileRuneEntry *)variable;
141 variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
142 if (variable > lastp) {
143 free(fdata);
144 errno = EFTYPE;
145 return (NULL);
146 }
147
148 frr = runetype_ext_ranges;
149 for (x = 0; x < frl->runetype_ext_nranges; ++x) {
150 uint32_t *types;
151
152 frr[x].min = ntohl(frr[x].min);
153 frr[x].max = ntohl(frr[x].max);
154 frr[x].map = ntohl(frr[x].map);
155 if (frr[x].map == 0) {
156 int len = frr[x].max - frr[x].min + 1;
157 types = variable;
158 variable = types + len;
159 runetype_ext_len += len;
160 if (variable > lastp) {
161 free(fdata);
162 errno = EFTYPE;
163 return (NULL);
164 }
165 while (len-- > 0)
166 types[len] = ntohl(types[len]);
167 }
168 }
169
170 frr = maplower_ext_ranges;
171 for (x = 0; x < frl->maplower_ext_nranges; ++x) {
172 frr[x].min = ntohl(frr[x].min);
173 frr[x].max = ntohl(frr[x].max);
174 frr[x].map = ntohl(frr[x].map);
175 }
176
177 frr = mapupper_ext_ranges;
178 for (x = 0; x < frl->mapupper_ext_nranges; ++x) {
179 frr[x].min = ntohl(frr[x].min);
180 frr[x].max = ntohl(frr[x].max);
181 frr[x].map = ntohl(frr[x].map);
182 }
183 if ((char *)variable + frl->variable_len > (char *)lastp) {
184 free(fdata);
185 errno = EFTYPE;
186 return (NULL);
187 }
188
189 /*
190 * Convert from disk format to host format.
191 */
192 data = malloc(sizeof(_RuneLocale) +
193 (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
194 frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
195 runetype_ext_len * sizeof(*rr->__types) +
196 frl->variable_len);
197 if (data == NULL) {
198 saverr = errno;
199 free(fdata);
200 errno = saverr;
201 return (NULL);
202 }
203
204 rl = (_RuneLocale *)data;
205 rl->__variable = rl + 1;
206
207 memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
208 memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
209 rl->__invalid_rune = 0;
210
211 rl->__variable_len = frl->variable_len;
212 rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
213 rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
214 rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
215
216 for (x = 0; x < _CACHED_RUNES; ++x) {
217 rl->__runetype[x] = frl->runetype[x];
218 rl->__maplower[x] = frl->maplower[x];
219 rl->__mapupper[x] = frl->mapupper[x];
220 }
221
222 rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
223 rl->__variable = rl->__runetype_ext.__ranges +
224 rl->__runetype_ext.__nranges;
225
226 rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
227 rl->__variable = rl->__maplower_ext.__ranges +
228 rl->__maplower_ext.__nranges;
229
230 rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
231 rl->__variable = rl->__mapupper_ext.__ranges +
232 rl->__mapupper_ext.__nranges;
233
234 variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
235 frr = runetype_ext_ranges;
236 rr = rl->__runetype_ext.__ranges;
237 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
238 uint32_t *types;
239
240 rr[x].__min = frr[x].min;
241 rr[x].__max = frr[x].max;
242 rr[x].__map = frr[x].map;
243 if (rr[x].__map == 0) {
244 int len = rr[x].__max - rr[x].__min + 1;
245 types = variable;
246 variable = types + len;
247 rr[x].__types = rl->__variable;
248 rl->__variable = rr[x].__types + len;
249 while (len-- > 0)
250 rr[x].__types[len] = types[len];
251 } else
252 rr[x].__types = NULL;
253 }
254
255 frr = maplower_ext_ranges;
256 rr = rl->__maplower_ext.__ranges;
257 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
258 rr[x].__min = frr[x].min;
259 rr[x].__max = frr[x].max;
260 rr[x].__map = frr[x].map;
261 }
262
263 frr = mapupper_ext_ranges;
264 rr = rl->__mapupper_ext.__ranges;
265 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
266 rr[x].__min = frr[x].min;
267 rr[x].__max = frr[x].max;
268 rr[x].__map = frr[x].map;
269 }
270
271 memcpy(rl->__variable, variable, rl->__variable_len);
272 free(fdata);
273
274 /*
275 * Go out and zero pointers that should be zero.
276 */
277 if (!rl->__variable_len)
278 rl->__variable = NULL;
279
280 if (!rl->__runetype_ext.__nranges)
281 rl->__runetype_ext.__ranges = NULL;
282
283 if (!rl->__maplower_ext.__nranges)
284 rl->__maplower_ext.__ranges = NULL;
285
286 if (!rl->__mapupper_ext.__nranges)
287 rl->__mapupper_ext.__ranges = NULL;
288
289 return (rl);
290}