rune.c revision 142582
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 $"); 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 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} 290