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) 38 static 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$"); 42 43 #include "namespace.h" 44 #include <arpa/inet.h> 45 #include <errno.h> 46 #include <runetype.h> 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 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 } 291