Print this page
5612 lpadmin dumps core in getlist

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/lp/lib/lp/getlist.c
          +++ new/usr/src/cmd/lp/lib/lp/getlist.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
       22 +
       23 +/*
       24 + *      Copyright 2015 Gary Mills
       25 + */
       26 +
  22   27  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  23   28  /*        All Rights Reserved   */
  24   29  
  25   30  
  26      -#ident  "%Z%%M% %I%     %E% SMI"        /* SVr4.0 1.13  */
  27   31  /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
  28   32  
  29   33  #include "string.h"
  30   34  #include "errno.h"
  31   35  #include "stdlib.h"
  32   36  
  33   37  #include "lp.h"
  34   38  
  35   39  #if     defined(__STDC__)
  36   40  static char             *unq_strdup ( char * , char * );
↓ open down ↓ 28 lines elided ↑ open up ↑
  65   69                                  *p,
  66   70                                  *sep,
  67   71                                  c;
  68   72  
  69   73          int                     n,
  70   74                                  len;
  71   75  
  72   76          char                    buf[10];
  73   77  
  74   78  
       79 +        char                    *copy,
       80 +                                *begin;
       81 +
  75   82          if (!str || !*str)
  76   83                  return (0);
  77   84  
  78   85          /*
  79   86           * Construct in "sep" the full list of characters that
  80   87           * can separate items in the list. Avoid a "malloc()"
  81   88           * if possible.
  82   89           */
  83   90          len = strlen(ws) + strlen(hardsep) + 1;
  84   91          if (len > sizeof(buf)) {
  85   92                  if (!(sep = Malloc(len))) {
  86   93                          errno = ENOMEM;
  87   94                          return (0);
  88   95                  }
  89   96          } else
  90   97                  sep = buf;
  91   98          strcpy (sep, hardsep);
  92   99          strcat (sep, ws);
  93  100  
  94  101          /*
      102 +         * Copy the input string because getlist() sometimes writes to it.
      103 +         */
      104 +        if (!(begin = Strdup(str))) {
      105 +                errno = ENOMEM;
      106 +                return (0);
      107 +        }
      108 +        copy = begin;
      109 +
      110 +        /*
  95  111           * Skip leading white-space.
  96  112           */
  97      -        str += strspn(str, ws);
  98      -        if (!*str)
      113 +        copy += strspn(copy, ws);
      114 +        if (!*copy) {
      115 +                Free (begin);
  99  116                  return (0);
      117 +        }
 100  118  
 101  119          /*
 102  120           * Strip trailing white-space.
 103  121           */
 104      -        p = strchr(str, '\0');
 105      -        while (--p != str && strchr(ws, *p))
      122 +        p = strchr(copy, '\0');
      123 +        while (--p != copy && strchr(ws, *p))
 106  124                  ;
 107  125          *++p = 0;
 108  126  
 109  127          /*
 110  128           * Pass 1: Count the number of items in the list.
 111  129           */
 112      -        for (n = 0, p = str; *p; ) {
      130 +        for (n = 0, p = copy; *p; ) {
 113  131                  if ((c = *p++) == '\\')
 114  132                          p++;
 115  133                  else
 116  134                          if (strchr(sep, c)) {
 117  135                                  n++;
 118  136                                  p += strspn(p, ws);
 119  137                                  if (
 120  138                                          !strchr(hardsep, c)
 121  139                                       && strchr(hardsep, *p)
 122  140                                  ) {
↓ open down ↓ 12 lines elided ↑ open up ↑
 135  153           * add 2 to the count (includes 1 for terminating null).
 136  154           */
 137  155          if (!(list = (char **)Malloc((n+2) * sizeof(char *)))) {
 138  156                  errno = ENOMEM;
 139  157                  goto Done;
 140  158          }
 141  159  
 142  160          /*
 143  161           * This loop will copy all but the last item.
 144  162           */
 145      -        for (n = 0, p = str; *p; )
      163 +        for (n = 0, p = copy; *p; )
 146  164                  if ((c = *p++) == '\\')
 147  165                          p++;
 148  166                  else
 149  167                          if (strchr(sep, c)) {
 150  168  
 151  169                                  p[-1] = 0;
 152      -                                list[n++] = unq_strdup(str, sep);
      170 +                                list[n++] = unq_strdup(copy, sep);
 153  171                                  p[-1] = c;
 154  172  
 155  173                                  p += strspn(p, ws);
 156  174                                  if (
 157  175                                          !strchr(hardsep, c)
 158  176                                       && strchr(hardsep, *p)
 159  177                                  ) {
 160  178                                          p++;
 161  179                                          p += strspn(p, ws);
 162  180                                  }
 163      -                                str = p;
      181 +                                copy = p;
 164  182  
 165  183                          }
 166  184  
 167      -        list[n++] = unq_strdup(str, sep);
      185 +        list[n++] = unq_strdup(copy, sep);
 168  186  
 169  187          list[n] = 0;
 170  188  
 171  189  Done:   if (sep != buf)
 172  190                  Free (sep);
      191 +        Free (begin);
 173  192          return (list);
 174  193  }
 175  194  
 176  195  /**
 177  196   ** unq_strdup()
 178  197   **/
 179  198  
 180  199  static char *
 181  200  #if     defined(__STDC__)
 182  201  unq_strdup (
↓ open down ↓ 27 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX