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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/rune.c
          +++ new/usr/src/lib/libc/port/locale/rune.c
   1    1  /*
        2 + * Copyright 2014 Garrett D'Amore <garrett@damore.org>
   2    3   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3    4   * Copyright (c) 1993
   4    5   *      The Regents of the University of California.  All rights reserved.
   5    6   *
   6    7   * This code is derived from software contributed to Berkeley by
   7    8   * Paul Borman at Krystal Technologies.
   8    9   *
   9   10   * Redistribution and use in source and binary forms, with or without
  10   11   * modification, are permitted provided that the following conditions
  11   12   * are met:
↓ open down ↓ 20 lines elided ↑ open up ↑
  32   33   */
  33   34  
  34   35  #include "lint.h"
  35   36  #include "file64.h"
  36   37  #include <errno.h>
  37   38  #include <stdio.h>
  38   39  #include <string.h>
  39   40  #include <stdlib.h>
  40   41  #include <sys/types.h>
  41   42  #include <sys/stat.h>
       43 +#include <sys/mman.h>
       44 +#include <fcntl.h>
       45 +#include <unistd.h>
  42   46  
       47 +#include "libc.h"
  43   48  #include "runetype.h"
  44   49  #include "runefile.h"
  45   50  
  46      -_RuneLocale *_Read_RuneMagi(FILE *);
  47      -
  48   51  _RuneLocale *
  49      -_Read_RuneMagi(FILE *fp)
       52 +_Read_RuneMagi(const char *fname)
  50   53  {
  51   54          char *fdata, *data;
  52   55          void *lastp;
  53   56          _FileRuneLocale *frl;
  54   57          _RuneLocale *rl;
  55   58          _FileRuneEntry *frr;
  56   59          _RuneEntry *rr;
  57   60          struct stat sb;
  58   61          int x, saverr;
  59   62          void *variable;
  60   63          _FileRuneEntry *runetype_ext_ranges;
  61   64          _FileRuneEntry *maplower_ext_ranges;
  62   65          _FileRuneEntry *mapupper_ext_ranges;
  63   66          int runetype_ext_len = 0;
       67 +        int fd;
  64   68  
  65      -        if (fstat(fileno(fp), &sb) < 0)
       69 +        if ((fd = open(fname, O_RDONLY)) < 0) {
       70 +                errno = EINVAL;
  66   71                  return (NULL);
       72 +        }
  67   73  
  68      -        if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
       74 +        if (fstat(fd, &sb) < 0) {
       75 +                (void) close(fd);
  69   76                  errno = EINVAL;
  70   77                  return (NULL);
  71   78          }
  72   79  
  73      -        if ((fdata = malloc(sb.st_size)) == NULL)
       80 +        if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
       81 +                (void) close(fd);
       82 +                errno = EINVAL;
  74   83                  return (NULL);
  75      -
  76      -        errno = 0;
  77      -        rewind(fp); /* Someone might have read the magic number once already */
  78      -        if (errno) {
  79      -                saverr = errno;
  80      -                free(fdata);
  81      -                errno = saverr;
  82      -                return (NULL);
  83   84          }
  84   85  
  85      -        if (fread(fdata, sb.st_size, 1, fp) != 1) {
  86      -                saverr = errno;
  87      -                free(fdata);
  88      -                errno = saverr;
       86 +
       87 +        fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
       88 +        (void) close(fd);
       89 +        if (fdata == NULL) {
       90 +                errno = EINVAL;
  89   91                  return (NULL);
  90   92          }
  91   93  
  92   94          frl = (_FileRuneLocale *)(void *)fdata;
  93   95          lastp = fdata + sb.st_size;
  94   96  
  95   97          variable = frl + 1;
  96   98  
  97   99          if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) {
  98      -                free(fdata);
  99      -                errno = EINVAL;
 100      -                return (NULL);
      100 +                goto invalid;
 101  101          }
 102  102  
 103  103          runetype_ext_ranges = (_FileRuneEntry *)variable;
 104  104          variable = runetype_ext_ranges + frl->runetype_ext_nranges;
 105  105          if (variable > lastp) {
 106      -                free(fdata);
 107      -                errno = EINVAL;
 108      -                return (NULL);
      106 +                goto invalid;
 109  107          }
 110  108  
 111  109          maplower_ext_ranges = (_FileRuneEntry *)variable;
 112  110          variable = maplower_ext_ranges + frl->maplower_ext_nranges;
 113  111          if (variable > lastp) {
 114      -                free(fdata);
 115      -                errno = EINVAL;
 116      -                return (NULL);
      112 +                goto invalid;
 117  113          }
 118  114  
 119  115          mapupper_ext_ranges = (_FileRuneEntry *)variable;
 120  116          variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
 121  117          if (variable > lastp) {
 122      -                free(fdata);
 123      -                errno = EINVAL;
 124      -                return (NULL);
      118 +                goto invalid;
 125  119          }
 126  120  
 127  121          frr = runetype_ext_ranges;
 128  122          for (x = 0; x < frl->runetype_ext_nranges; ++x) {
 129  123                  uint32_t *types;
 130  124  
 131  125                  if (frr[x].map == 0) {
 132  126                          int len = frr[x].max - frr[x].min + 1;
 133  127                          types = variable;
 134  128                          variable = types + len;
 135  129                          runetype_ext_len += len;
 136  130                          if (variable > lastp) {
 137      -                                free(fdata);
 138      -                                errno = EINVAL;
 139      -                                return (NULL);
      131 +                                goto invalid;
 140  132                          }
 141  133                  }
 142  134          }
 143  135  
 144  136          if ((char *)variable + frl->variable_len > (char *)lastp) {
 145      -                free(fdata);
 146      -                errno = EINVAL;
 147      -                return (NULL);
      137 +                goto invalid;
 148  138          }
 149  139  
 150  140          /*
 151  141           * Convert from disk format to host format.
 152  142           */
 153      -        data = malloc(sizeof (_RuneLocale) +
      143 +        data = libc_malloc(sizeof (_RuneLocale) +
 154  144              (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
 155  145              frl->mapupper_ext_nranges) * sizeof (_RuneEntry) +
 156  146              runetype_ext_len * sizeof (*rr->__types) +
 157  147              frl->variable_len);
 158  148          if (data == NULL) {
 159  149                  saverr = errno;
 160      -                free(fdata);
      150 +                (void) munmap(fdata, sb.st_size);
 161  151                  errno = saverr;
 162  152                  return (NULL);
 163  153          }
 164  154  
 165  155          rl = (_RuneLocale *)(void *)data;
 166  156          rl->__variable = rl + 1;
 167  157  
 168  158          (void) memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof (rl->__magic));
 169  159          (void) memcpy(rl->__encoding, frl->encoding, sizeof (rl->__encoding));
 170  160  
↓ open down ↓ 51 lines elided ↑ open up ↑
 222  212  
 223  213          frr = mapupper_ext_ranges;
 224  214          rr = rl->__mapupper_ext.__ranges;
 225  215          for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
 226  216                  rr[x].__min = frr[x].min;
 227  217                  rr[x].__max = frr[x].max;
 228  218                  rr[x].__map = frr[x].map;
 229  219          }
 230  220  
 231  221          (void) memcpy(rl->__variable, variable, rl->__variable_len);
 232      -        free(fdata);
      222 +        (void) munmap(fdata, sb.st_size);
 233  223  
 234  224          /*
 235  225           * Go out and zero pointers that should be zero.
 236  226           */
 237  227          if (!rl->__variable_len)
 238  228                  rl->__variable = NULL;
 239  229  
 240  230          if (!rl->__runetype_ext.__nranges)
 241  231                  rl->__runetype_ext.__ranges = NULL;
 242  232  
 243  233          if (!rl->__maplower_ext.__nranges)
 244  234                  rl->__maplower_ext.__ranges = NULL;
 245  235  
 246  236          if (!rl->__mapupper_ext.__nranges)
 247  237                  rl->__mapupper_ext.__ranges = NULL;
 248  238  
 249  239          return (rl);
      240 +
      241 +invalid:
      242 +        (void) munmap(fdata, sb.st_size);
      243 +        errno = EINVAL;
      244 +        return (NULL);
 250  245  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX