Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Approved by: TBD

*** 1,6 **** --- 1,7 ---- /* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by
*** 37,54 **** #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include "runetype.h" #include "runefile.h" - _RuneLocale *_Read_RuneMagi(FILE *); - _RuneLocale * ! _Read_RuneMagi(FILE *fp) { char *fdata, *data; void *lastp; _FileRuneLocale *frl; _RuneLocale *rl; --- 38,57 ---- #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> + #include <sys/mman.h> + #include <fcntl.h> + #include <unistd.h> + #include "libc.h" #include "runetype.h" #include "runefile.h" _RuneLocale * ! _Read_RuneMagi(const char *fname) { char *fdata, *data; void *lastp; _FileRuneLocale *frl; _RuneLocale *rl;
*** 59,129 **** void *variable; _FileRuneEntry *runetype_ext_ranges; _FileRuneEntry *maplower_ext_ranges; _FileRuneEntry *mapupper_ext_ranges; int runetype_ext_len = 0; ! if (fstat(fileno(fp), &sb) < 0) return (NULL); ! if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) { errno = EINVAL; return (NULL); } ! if ((fdata = malloc(sb.st_size)) == 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; ! free(fdata); ! errno = saverr; return (NULL); } frl = (_FileRuneLocale *)(void *)fdata; lastp = fdata + sb.st_size; variable = frl + 1; if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } runetype_ext_ranges = (_FileRuneEntry *)variable; variable = runetype_ext_ranges + frl->runetype_ext_nranges; if (variable > lastp) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } maplower_ext_ranges = (_FileRuneEntry *)variable; variable = maplower_ext_ranges + frl->maplower_ext_nranges; if (variable > lastp) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } mapupper_ext_ranges = (_FileRuneEntry *)variable; variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; if (variable > lastp) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } frr = runetype_ext_ranges; for (x = 0; x < frl->runetype_ext_nranges; ++x) { uint32_t *types; --- 62,123 ---- void *variable; _FileRuneEntry *runetype_ext_ranges; _FileRuneEntry *maplower_ext_ranges; _FileRuneEntry *mapupper_ext_ranges; int runetype_ext_len = 0; + int fd; ! if ((fd = open(fname, O_RDONLY)) < 0) { ! errno = EINVAL; return (NULL); + } ! if (fstat(fd, &sb) < 0) { ! (void) close(fd); errno = EINVAL; return (NULL); } ! if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) { ! (void) close(fd); ! errno = EINVAL; return (NULL); } ! ! fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); ! (void) close(fd); ! if (fdata == NULL) { ! errno = EINVAL; return (NULL); } frl = (_FileRuneLocale *)(void *)fdata; lastp = fdata + sb.st_size; variable = frl + 1; if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) { ! goto invalid; } runetype_ext_ranges = (_FileRuneEntry *)variable; variable = runetype_ext_ranges + frl->runetype_ext_nranges; if (variable > lastp) { ! goto invalid; } maplower_ext_ranges = (_FileRuneEntry *)variable; variable = maplower_ext_ranges + frl->maplower_ext_nranges; if (variable > lastp) { ! goto invalid; } mapupper_ext_ranges = (_FileRuneEntry *)variable; variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; if (variable > lastp) { ! goto invalid; } frr = runetype_ext_ranges; for (x = 0; x < frl->runetype_ext_nranges; ++x) { uint32_t *types;
*** 132,165 **** int len = frr[x].max - frr[x].min + 1; types = variable; variable = types + len; runetype_ext_len += len; if (variable > lastp) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } } } if ((char *)variable + frl->variable_len > (char *)lastp) { ! free(fdata); ! errno = EINVAL; ! return (NULL); } /* * Convert from disk format to host format. */ ! data = malloc(sizeof (_RuneLocale) + (frl->runetype_ext_nranges + frl->maplower_ext_nranges + frl->mapupper_ext_nranges) * sizeof (_RuneEntry) + runetype_ext_len * sizeof (*rr->__types) + frl->variable_len); if (data == NULL) { saverr = errno; ! free(fdata); errno = saverr; return (NULL); } rl = (_RuneLocale *)(void *)data; --- 126,155 ---- int len = frr[x].max - frr[x].min + 1; types = variable; variable = types + len; runetype_ext_len += len; if (variable > lastp) { ! goto invalid; } } } if ((char *)variable + frl->variable_len > (char *)lastp) { ! goto invalid; } /* * Convert from disk format to host format. */ ! data = libc_malloc(sizeof (_RuneLocale) + (frl->runetype_ext_nranges + frl->maplower_ext_nranges + frl->mapupper_ext_nranges) * sizeof (_RuneEntry) + runetype_ext_len * sizeof (*rr->__types) + frl->variable_len); if (data == NULL) { saverr = errno; ! (void) munmap(fdata, sb.st_size); errno = saverr; return (NULL); } rl = (_RuneLocale *)(void *)data;
*** 227,237 **** rr[x].__max = frr[x].max; rr[x].__map = frr[x].map; } (void) memcpy(rl->__variable, variable, rl->__variable_len); ! free(fdata); /* * Go out and zero pointers that should be zero. */ if (!rl->__variable_len) --- 217,227 ---- rr[x].__max = frr[x].max; rr[x].__map = frr[x].map; } (void) memcpy(rl->__variable, variable, rl->__variable_len); ! (void) munmap(fdata, sb.st_size); /* * Go out and zero pointers that should be zero. */ if (!rl->__variable_len)
*** 245,250 **** --- 235,245 ---- if (!rl->__mapupper_ext.__nranges) rl->__mapupper_ext.__ranges = NULL; return (rl); + + invalid: + (void) munmap(fdata, sb.st_size); + errno = EINVAL; + return (NULL); }