Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/locale/rune.c
/*- | /*- | ||||
* Copyright 2014 Garrett D'Amore <garrett@damore.org> | |||||
* Copyright 2010 Nexenta Systems, Inc. All rights reserved. | |||||
* Copyright (c) 1993 | * Copyright (c) 1993 | ||||
* The Regents of the University of California. All rights reserved. | * The Regents of the University of California. All rights reserved. | ||||
* | * | ||||
* This code is derived from software contributed to Berkeley by | * This code is derived from software contributed to Berkeley by | ||||
* Paul Borman at Krystal Technologies. | * Paul Borman at Krystal Technologies. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
Show All 30 Lines | |||||
#include <arpa/inet.h> | #include <arpa/inet.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <runetype.h> | #include <runetype.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/mman.h> | |||||
#include <fcntl.h> | |||||
#include <unistd.h> | |||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
#include "runefile.h" | #include "runefile.h" | ||||
_RuneLocale *_Read_RuneMagi(FILE *); | |||||
_RuneLocale * | _RuneLocale * | ||||
_Read_RuneMagi(FILE *fp) | _Read_RuneMagi(const char *fname) | ||||
{ | { | ||||
char *fdata, *data; | char *fdata, *data; | ||||
void *lastp; | void *lastp; | ||||
_FileRuneLocale *frl; | _FileRuneLocale *frl; | ||||
_RuneLocale *rl; | _RuneLocale *rl; | ||||
_FileRuneEntry *frr; | _FileRuneEntry *frr; | ||||
_RuneEntry *rr; | _RuneEntry *rr; | ||||
struct stat sb; | struct stat sb; | ||||
int x, saverr; | int x, saverr; | ||||
void *variable; | void *variable; | ||||
_FileRuneEntry *runetype_ext_ranges; | _FileRuneEntry *runetype_ext_ranges; | ||||
_FileRuneEntry *maplower_ext_ranges; | _FileRuneEntry *maplower_ext_ranges; | ||||
_FileRuneEntry *mapupper_ext_ranges; | _FileRuneEntry *mapupper_ext_ranges; | ||||
int runetype_ext_len = 0; | int runetype_ext_len = 0; | ||||
int fd; | |||||
if (_fstat(fileno(fp), &sb) < 0) | if ((fd = _open(fname, O_RDONLY)) < 0) { | ||||
errno = EINVAL; | |||||
return (NULL); | return (NULL); | ||||
} | |||||
if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) { | if (_fstat(fd, &sb) < 0) { | ||||
errno = EFTYPE; | (void) _close(fd); | ||||
errno = EINVAL; | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if ((fdata = malloc(sb.st_size)) == NULL) | if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) { | ||||
(void) _close(fd); | |||||
errno = EINVAL; | |||||
return (NULL); | return (NULL); | ||||
errno = 0; | |||||
rewind(fp); /* Someone might have read the magic number once already */ | |||||
if (errno) { | |||||
saverr = errno; | |||||
free(fdata); | |||||
errno = saverr; | |||||
return (NULL); | |||||
} | } | ||||
if (fread(fdata, sb.st_size, 1, fp) != 1) { | |||||
saverr = errno; | fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | ||||
free(fdata); | (void) _close(fd); | ||||
errno = saverr; | if (fdata == NULL) { | ||||
errno = EINVAL; | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
frl = (_FileRuneLocale *)fdata; | frl = (_FileRuneLocale *)(void *)fdata; | ||||
lastp = fdata + sb.st_size; | lastp = fdata + sb.st_size; | ||||
variable = frl + 1; | variable = frl + 1; | ||||
if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) { | if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
frl->variable_len = ntohl(frl->variable_len); | |||||
frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges); | |||||
frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges); | |||||
frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges); | |||||
for (x = 0; x < _CACHED_RUNES; ++x) { | |||||
frl->runetype[x] = ntohl(frl->runetype[x]); | |||||
frl->maplower[x] = ntohl(frl->maplower[x]); | |||||
frl->mapupper[x] = ntohl(frl->mapupper[x]); | |||||
} | |||||
runetype_ext_ranges = (_FileRuneEntry *)variable; | runetype_ext_ranges = (_FileRuneEntry *)variable; | ||||
variable = runetype_ext_ranges + frl->runetype_ext_nranges; | variable = runetype_ext_ranges + frl->runetype_ext_nranges; | ||||
if (variable > lastp) { | if (variable > lastp) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
maplower_ext_ranges = (_FileRuneEntry *)variable; | maplower_ext_ranges = (_FileRuneEntry *)variable; | ||||
variable = maplower_ext_ranges + frl->maplower_ext_nranges; | variable = maplower_ext_ranges + frl->maplower_ext_nranges; | ||||
if (variable > lastp) { | if (variable > lastp) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
mapupper_ext_ranges = (_FileRuneEntry *)variable; | mapupper_ext_ranges = (_FileRuneEntry *)variable; | ||||
variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; | variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; | ||||
if (variable > lastp) { | if (variable > lastp) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
frr = runetype_ext_ranges; | frr = runetype_ext_ranges; | ||||
for (x = 0; x < frl->runetype_ext_nranges; ++x) { | for (x = 0; x < frl->runetype_ext_nranges; ++x) { | ||||
uint32_t *types; | uint32_t *types; | ||||
frr[x].min = ntohl(frr[x].min); | |||||
frr[x].max = ntohl(frr[x].max); | |||||
frr[x].map = ntohl(frr[x].map); | |||||
if (frr[x].map == 0) { | if (frr[x].map == 0) { | ||||
int len = frr[x].max - frr[x].min + 1; | int len = frr[x].max - frr[x].min + 1; | ||||
types = variable; | types = variable; | ||||
variable = types + len; | variable = types + len; | ||||
runetype_ext_len += len; | runetype_ext_len += len; | ||||
if (variable > lastp) { | if (variable > lastp) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
while (len-- > 0) | |||||
types[len] = ntohl(types[len]); | |||||
} | } | ||||
} | } | ||||
frr = maplower_ext_ranges; | |||||
for (x = 0; x < frl->maplower_ext_nranges; ++x) { | |||||
frr[x].min = ntohl(frr[x].min); | |||||
frr[x].max = ntohl(frr[x].max); | |||||
frr[x].map = ntohl(frr[x].map); | |||||
} | |||||
frr = mapupper_ext_ranges; | |||||
for (x = 0; x < frl->mapupper_ext_nranges; ++x) { | |||||
frr[x].min = ntohl(frr[x].min); | |||||
frr[x].max = ntohl(frr[x].max); | |||||
frr[x].map = ntohl(frr[x].map); | |||||
} | |||||
if ((char *)variable + frl->variable_len > (char *)lastp) { | if ((char *)variable + frl->variable_len > (char *)lastp) { | ||||
free(fdata); | goto invalid; | ||||
errno = EFTYPE; | |||||
return (NULL); | |||||
} | } | ||||
/* | /* | ||||
* Convert from disk format to host format. | * Convert from disk format to host format. | ||||
*/ | */ | ||||
data = malloc(sizeof(_RuneLocale) + | data = malloc(sizeof(_RuneLocale) + | ||||
(frl->runetype_ext_nranges + frl->maplower_ext_nranges + | (frl->runetype_ext_nranges + frl->maplower_ext_nranges + | ||||
frl->mapupper_ext_nranges) * sizeof(_RuneEntry) + | frl->mapupper_ext_nranges) * sizeof(_RuneEntry) + | ||||
runetype_ext_len * sizeof(*rr->__types) + | runetype_ext_len * sizeof(*rr->__types) + | ||||
frl->variable_len); | frl->variable_len); | ||||
if (data == NULL) { | if (data == NULL) { | ||||
saverr = errno; | saverr = errno; | ||||
free(fdata); | munmap(fdata, sb.st_size); | ||||
errno = saverr; | errno = saverr; | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
rl = (_RuneLocale *)data; | rl = (_RuneLocale *)data; | ||||
rl->__variable = rl + 1; | rl->__variable = rl + 1; | ||||
memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); | memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); | ||||
memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); | memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); | ||||
rl->__invalid_rune = 0; | |||||
rl->__variable_len = frl->variable_len; | rl->__variable_len = frl->variable_len; | ||||
rl->__runetype_ext.__nranges = frl->runetype_ext_nranges; | rl->__runetype_ext.__nranges = frl->runetype_ext_nranges; | ||||
rl->__maplower_ext.__nranges = frl->maplower_ext_nranges; | rl->__maplower_ext.__nranges = frl->maplower_ext_nranges; | ||||
rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges; | rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges; | ||||
for (x = 0; x < _CACHED_RUNES; ++x) { | for (x = 0; x < _CACHED_RUNES; ++x) { | ||||
rl->__runetype[x] = frl->runetype[x]; | rl->__runetype[x] = frl->runetype[x]; | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | _Read_RuneMagi(const char *fname) | ||||
rr = rl->__mapupper_ext.__ranges; | rr = rl->__mapupper_ext.__ranges; | ||||
for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { | for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { | ||||
rr[x].__min = frr[x].min; | rr[x].__min = frr[x].min; | ||||
rr[x].__max = frr[x].max; | rr[x].__max = frr[x].max; | ||||
rr[x].__map = frr[x].map; | rr[x].__map = frr[x].map; | ||||
} | } | ||||
memcpy(rl->__variable, variable, rl->__variable_len); | memcpy(rl->__variable, variable, rl->__variable_len); | ||||
free(fdata); | munmap(fdata, sb.st_size); | ||||
/* | /* | ||||
* Go out and zero pointers that should be zero. | * Go out and zero pointers that should be zero. | ||||
*/ | */ | ||||
if (!rl->__variable_len) | if (!rl->__variable_len) | ||||
rl->__variable = NULL; | rl->__variable = NULL; | ||||
if (!rl->__runetype_ext.__nranges) | if (!rl->__runetype_ext.__nranges) | ||||
rl->__runetype_ext.__ranges = NULL; | rl->__runetype_ext.__ranges = NULL; | ||||
if (!rl->__maplower_ext.__nranges) | if (!rl->__maplower_ext.__nranges) | ||||
rl->__maplower_ext.__ranges = NULL; | rl->__maplower_ext.__ranges = NULL; | ||||
if (!rl->__mapupper_ext.__nranges) | if (!rl->__mapupper_ext.__nranges) | ||||
rl->__mapupper_ext.__ranges = NULL; | rl->__mapupper_ext.__ranges = NULL; | ||||
return (rl); | return (rl); | ||||
invalid: | |||||
munmap(fdata, sb.st_size); | |||||
errno = EINVAL; | |||||
return (NULL); | |||||
} | } |