Print this page
locale stuff should use libc safe lmalloc.  Other fixes from tests.

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/localeimpl.c
          +++ new/usr/src/lib/libc/port/locale/localeimpl.c
↓ open down ↓ 150 lines elided ↑ open up ↑
 151  151  
 152  152  /*
 153  153   * Some utility routines.
 154  154   */
 155  155  
 156  156  struct locdata *
 157  157  __locdata_alloc(const char *name, size_t memsz)
 158  158  {
 159  159          struct locdata *ldata;
 160  160  
 161      -        if ((ldata = calloc(1, sizeof (*ldata))) == NULL) {
      161 +        if ((ldata = lmalloc(sizeof (*ldata))) == NULL) {
 162  162                  return (NULL);
 163  163          }
 164      -        if ((ldata->l_data[0] = calloc(1, memsz)) == NULL) {
 165      -                free(ldata);
      164 +        if ((ldata->l_data[0] = libc_malloc(memsz)) == NULL) {
      165 +                lfree(ldata, sizeof (*ldata));
 166  166                  errno = ENOMEM;
 167  167                  return (NULL);
 168  168          }
 169  169          (void) strlcpy(ldata->l_lname, name, sizeof (ldata->l_lname));
 170  170  
 171  171          return (ldata);
 172  172  }
 173  173  
 174  174  /*
 175  175   * Normally we never free locale data truly, but if we failed to load it
 176  176   * for some reason, this routine is used to cleanup the partial mess.
 177  177   */
 178  178  void
 179  179  __locdata_free(struct locdata *ldata)
 180  180  {
 181  181          for (int i = 0; i < NLOCDATA; i++)
 182      -                free(ldata->l_data[i]);
      182 +                libc_free(ldata->l_data[i]);
 183  183          if (ldata->l_map != NULL && ldata->l_map_len)
 184  184                  (void) munmap(ldata->l_map, ldata->l_map_len);
 185      -        free(ldata);
      185 +        lfree(ldata, sizeof (*ldata));
 186  186  }
 187  187  
 188  188  /*
 189  189   * It turns out that for performance reasons we would really like to
 190  190   * cache the most recently referenced locale data to avoid wasteful
 191  191   * loading from files.
 192  192   */
 193  193  
 194  194  static struct locdata *cache_data[LC_ALL];
 195  195  static struct locdata *cat_data[LC_ALL];
↓ open down ↓ 47 lines elided ↑ open up ↑
 243  243           * This wastes the memory for an extra copy of the locale
 244  244           * data, but there is no further harm beyond that.  Its not
 245  245           * worth the effort to recode this to something "safe"
 246  246           * (which would require rescanning the list, etc.), given
 247  247           * that this race will probably never actually occur.
 248  248           */
 249  249          if (loc == NULL) {
 250  250                  lmutex_unlock(&cache_lock);
 251  251                  loc = (*loaders[category])(locname);
 252  252                  lmutex_lock(&cache_lock);
 253      -                (void) strlcpy(loc->l_lname, locname, sizeof (loc->l_lname));
      253 +                if (loc != NULL)
      254 +                        (void) strlcpy(loc->l_lname, locname,
      255 +                            sizeof (loc->l_lname));
 254  256          }
 255  257  
 256  258          /*
 257  259           * Assuming we got one, update the cache, and stick us on the list
 258  260           * of loaded locale data.  We insert into the head (more recent
 259  261           * use is likely to win.)
 260  262           */
 261  263          if (loc != NULL) {
 262  264                  cache_data[category] = loc;
 263      -                if (loc->l_next == NULL) {
      265 +                if (!loc->l_cached) {
      266 +                        loc->l_cached = 1;
 264  267                          loc->l_next = cat_data[category];
 265  268                          cat_data[category] = loc;
 266  269                  }
 267  270          }
 268  271  
 269  272          lmutex_unlock(&cache_lock);
 270  273          return (loc);
 271  274  }
 272  275  
 273  276  /*
↓ open down ↓ 93 lines elided ↑ open up ↑
 367  370  /*
 368  371   * Public interfaces.
 369  372   */
 370  373  
 371  374  locale_t
 372  375  duplocale(locale_t src)
 373  376  {
 374  377          locale_t        loc;
 375  378          int             i;
 376  379  
 377      -        loc = calloc(1, sizeof (*loc));
      380 +        loc = lmalloc(sizeof (*loc));
 378  381          if (loc == NULL) {
 379  382                  return (NULL);
 380  383          }
 381  384          if (src == NULL) {
 382  385                  /* illumos extension: POSIX says LC_GLOBAL_LOCALE here */
 383  386                  src = ___global_locale;
 384  387          }
 385  388          for (i = 0; i < LC_ALL; i++) {
 386  389                  loc->locdata[i] = src->locdata[i];
 387  390                  loc->loaded[i] = 0;
↓ open down ↓ 9 lines elided ↑ open up ↑
 397  400  }
 398  401  
 399  402  void
 400  403  freelocale(locale_t loc)
 401  404  {
 402  405          /*
 403  406           * We take extra care never to free a saved locale created by
 404  407           * setlocale().  This shouldn't be strictly necessary, but a little
 405  408           * extra safety doesn't hurt here.
 406  409           */
 407      -        if ((loc != &posix_locale) && (!loc->on_list))
 408      -                free(loc);
      410 +        if ((loc != NULL) && (loc != &posix_locale) && (!loc->on_list))
      411 +                lfree(loc, sizeof (*loc));
 409  412  }
 410  413  
 411  414  locale_t
 412  415  newlocale(int catmask, const char *locname, locale_t base)
 413  416  {
 414  417          locale_t loc;
 415  418          int i, e;
 416  419  
 417  420          if (catmask & ~(LC_ALL_MASK)) {
 418  421                  errno = EINVAL;
 419  422                  return (NULL);
 420  423          }
 421  424  
 422  425          /*
 423  426           * Technically passing LC_GLOBAL_LOCALE here is illegal,
 424  427           * but we allow it.
 425  428           */
 426  429          if (base == NULL || base == ___global_locale) {
 427  430                  loc = duplocale(___global_locale);
 428  431          } else {
 429      -                loc = base;
      432 +                loc = duplocale(base);
 430  433          }
 431  434          if (loc == NULL) {
 432  435                  return (NULL);
 433  436          }
 434  437  
 435  438          for (i = 0; i < LC_ALL; i++) {
 436  439                  struct locdata *ldata;
 437  440                  loc->loaded[i] = 0;
 438  441                  if (((1 << i) & catmask) == 0) {
 439  442                          /* Default to base locale if not overriding */
↓ open down ↓ 8 lines elided ↑ open up ↑
 448  451                  }
 449  452                  loc->locdata[i] = ldata;
 450  453          }
 451  454          loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
 452  455          loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
 453  456          loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
 454  457          loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
 455  458          loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
 456  459          loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
 457  460          loc->time = loc->locdata[LC_TIME]->l_data[0];
      461 +        freelocale(base);
      462 +
 458  463          return (mklocname(loc));
 459  464  }
 460  465  
 461  466  locale_t
 462  467  uselocale(locale_t loc)
 463  468  {
 464  469          locale_t lastloc = ___global_locale;
 465  470          locale_t *locptr;
 466  471  
 467  472          locptr = tsdalloc(_T_SETLOCALE, sizeof (locale_t), freelocptr);
↓ open down ↓ 65 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX