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);
}