Author: dumbbell
Date: Tue Nov  9 20:56:55 2010
New Revision: 215055
URL: http://svn.freebsd.org/changeset/base/215055

Log:
  MFC r214893:
  Fix a segmentation fault in argument processing.
  
  The crash was caused by a command line such as this one:
  # fold -b1
  
  PR:           bin/151592
  Reported by:  Marcus Reid <mar...@blazingdot.com>
  Tested by:    Marcus Reid <mar...@blazingdot.com>

Modified:
  stable/7/usr.bin/fold/fold.c
Directory Properties:
  stable/7/usr.bin/fold/   (props changed)

Modified: stable/7/usr.bin/fold/fold.c
==============================================================================
--- stable/7/usr.bin/fold/fold.c        Tue Nov  9 20:46:41 2010        
(r215054)
+++ stable/7/usr.bin/fold/fold.c        Tue Nov  9 20:56:55 2010        
(r215055)
@@ -71,14 +71,14 @@ int sflag;                  /* Split on word boundaries
 int
 main(int argc, char **argv)
 {
-       int ch;
+       int ch, previous_ch;
        int rval, width;
-       char *p;
 
        (void) setlocale(LC_CTYPE, "");
 
        width = -1;
-       while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
+       previous_ch = 0;
+       while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) {
                switch (ch) {
                case 'b':
                        bflag = 1;
@@ -93,17 +93,33 @@ main(int argc, char **argv)
                        break;
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
-                       if (width == -1) {
-                               p = argv[optind - 1];
-                               if (p[0] == '-' && p[1] == ch && !p[2])
-                                       width = atoi(++p);
-                               else
-                                       width = atoi(argv[optind] + 1);
+                       /* Accept a width as eg. -30. Note that a width
+                        * specified using the -w option is always used prior
+                        * to this undocumented option. */
+                       switch (previous_ch) {
+                       case '0': case '1': case '2': case '3': case '4':
+                       case '5': case '6': case '7': case '8': case '9':
+                               /* The width is a number with multiple digits:
+                                * add the last one. */
+                               width = width * 10 + (ch - '0');
+                               break;
+                       default:
+                               /* Set the width, unless it was previously
+                                * set. For instance, the following options
+                                * would all give a width of 5 and not 10:
+                                *   -10 -w5
+                                *   -5b10
+                                *   -5 -10b */
+                               if (width == -1)
+                                       width = ch - '0';
+                               break;
                        }
                        break;
                default:
                        usage();
                }
+               previous_ch = ch;
+       }
        argv += optind;
        argc -= optind;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to