Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>

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  
  43   47  #include "runetype.h"
  44   48  #include "runefile.h"
  45   49  
  46      -_RuneLocale *_Read_RuneMagi(FILE *);
  47      -
  48   50  _RuneLocale *
  49      -_Read_RuneMagi(FILE *fp)
       51 +_Read_RuneMagi(const char *fname)
  50   52  {
  51   53          char *fdata, *data;
  52   54          void *lastp;
  53   55          _FileRuneLocale *frl;
  54   56          _RuneLocale *rl;
  55   57          _FileRuneEntry *frr;
  56   58          _RuneEntry *rr;
  57   59          struct stat sb;
  58   60          int x, saverr;
  59   61          void *variable;
  60   62          _FileRuneEntry *runetype_ext_ranges;
  61   63          _FileRuneEntry *maplower_ext_ranges;
  62   64          _FileRuneEntry *mapupper_ext_ranges;
  63   65          int runetype_ext_len = 0;
       66 +        int fd;
  64   67  
  65      -        if (fstat(fileno(fp), &sb) < 0)
       68 +        if ((fd = open(fname, O_RDONLY)) < 0) {
       69 +                errno = EINVAL;
  66   70                  return (NULL);
       71 +        }
  67   72  
  68      -        if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
       73 +        if (fstat(fd, &sb) < 0) {
       74 +                (void) close(fd);
  69   75                  errno = EINVAL;
  70   76                  return (NULL);
  71   77          }
  72   78  
  73      -        if ((fdata = malloc(sb.st_size)) == NULL)
       79 +        if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
       80 +                (void) close(fd);
       81 +                errno = EINVAL;
  74   82                  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   83          }
  84   84  
  85      -        if (fread(fdata, sb.st_size, 1, fp) != 1) {
  86      -                saverr = errno;
  87      -                free(fdata);
  88      -                errno = saverr;
       85 +
       86 +        fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
       87 +        (void) close(fd);
       88 +        if (fdata == NULL) {
       89 +                errno = EINVAL;
  89   90                  return (NULL);
  90   91          }
  91   92  
  92   93          frl = (_FileRuneLocale *)(void *)fdata;
  93   94          lastp = fdata + sb.st_size;
  94   95  
  95   96          variable = frl + 1;
  96   97  
  97   98          if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) {
  98      -                free(fdata);
  99      -                errno = EINVAL;
 100      -                return (NULL);
       99 +                goto invalid;
 101  100          }
 102  101  
 103  102          runetype_ext_ranges = (_FileRuneEntry *)variable;
 104  103          variable = runetype_ext_ranges + frl->runetype_ext_nranges;
 105  104          if (variable > lastp) {
 106      -                free(fdata);
 107      -                errno = EINVAL;
 108      -                return (NULL);
      105 +                goto invalid;
 109  106          }
 110  107  
 111  108          maplower_ext_ranges = (_FileRuneEntry *)variable;
 112  109          variable = maplower_ext_ranges + frl->maplower_ext_nranges;
 113  110          if (variable > lastp) {
 114      -                free(fdata);
 115      -                errno = EINVAL;
 116      -                return (NULL);
      111 +                goto invalid;
 117  112          }
 118  113  
 119  114          mapupper_ext_ranges = (_FileRuneEntry *)variable;
 120  115          variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
 121  116          if (variable > lastp) {
 122      -                free(fdata);
 123      -                errno = EINVAL;
 124      -                return (NULL);
      117 +                goto invalid;
 125  118          }
 126  119  
 127  120          frr = runetype_ext_ranges;
 128  121          for (x = 0; x < frl->runetype_ext_nranges; ++x) {
 129  122                  uint32_t *types;
 130  123  
 131  124                  if (frr[x].map == 0) {
 132  125                          int len = frr[x].max - frr[x].min + 1;
 133  126                          types = variable;
 134  127                          variable = types + len;
 135  128                          runetype_ext_len += len;
 136  129                          if (variable > lastp) {
 137      -                                free(fdata);
 138      -                                errno = EINVAL;
 139      -                                return (NULL);
      130 +                                goto invalid;
 140  131                          }
 141  132                  }
 142  133          }
 143  134  
 144  135          if ((char *)variable + frl->variable_len > (char *)lastp) {
 145      -                free(fdata);
 146      -                errno = EINVAL;
 147      -                return (NULL);
      136 +                goto invalid;
 148  137          }
 149  138  
 150  139          /*
 151  140           * Convert from disk format to host format.
 152  141           */
 153  142          data = malloc(sizeof (_RuneLocale) +
 154  143              (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
 155  144              frl->mapupper_ext_nranges) * sizeof (_RuneEntry) +
 156  145              runetype_ext_len * sizeof (*rr->__types) +
 157  146              frl->variable_len);
 158  147          if (data == NULL) {
 159  148                  saverr = errno;
 160      -                free(fdata);
      149 +                (void) munmap(fdata, sb.st_size);
 161  150                  errno = saverr;
 162  151                  return (NULL);
 163  152          }
 164  153  
 165  154          rl = (_RuneLocale *)(void *)data;
 166  155          rl->__variable = rl + 1;
 167  156  
 168  157          (void) memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof (rl->__magic));
 169  158          (void) memcpy(rl->__encoding, frl->encoding, sizeof (rl->__encoding));
 170  159  
↓ open down ↓ 51 lines elided ↑ open up ↑
 222  211  
 223  212          frr = mapupper_ext_ranges;
 224  213          rr = rl->__mapupper_ext.__ranges;
 225  214          for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
 226  215                  rr[x].__min = frr[x].min;
 227  216                  rr[x].__max = frr[x].max;
 228  217                  rr[x].__map = frr[x].map;
 229  218          }
 230  219  
 231  220          (void) memcpy(rl->__variable, variable, rl->__variable_len);
 232      -        free(fdata);
      221 +        (void) munmap(fdata, sb.st_size);
 233  222  
 234  223          /*
 235  224           * Go out and zero pointers that should be zero.
 236  225           */
 237  226          if (!rl->__variable_len)
 238  227                  rl->__variable = NULL;
 239  228  
 240  229          if (!rl->__runetype_ext.__nranges)
 241  230                  rl->__runetype_ext.__ranges = NULL;
 242  231  
 243  232          if (!rl->__maplower_ext.__nranges)
 244  233                  rl->__maplower_ext.__ranges = NULL;
 245  234  
 246  235          if (!rl->__mapupper_ext.__nranges)
 247  236                  rl->__mapupper_ext.__ranges = NULL;
 248  237  
 249  238          return (rl);
      239 +
      240 +invalid:
      241 +        (void) munmap(fdata, sb.st_size);
      242 +        errno = EINVAL;
      243 +        return (NULL);
 250  244  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX