svn commit: r214893 - head/usr.bin/fold

Jean-Sebastien Pedron dumbbell at FreeBSD.org
Sat Nov 6 17:48:46 UTC 2010


Author: dumbbell
Date: Sat Nov  6 17:48:46 2010
New Revision: 214893
URL: http://svn.freebsd.org/changeset/base/214893

Log:
  Fix a segmentation fault in argument processing.
  
  The crash was caused by a command line such as this one:
  # foldl -b1
  
  PR:		bin/151592
  Reported by:	Marcus Reid <marcus at blazingdot.com>
  Tested by:	Marcus Reid <marcus at blazingdot.com>
  MFC after:	3 days

Modified:
  head/usr.bin/fold/fold.c

Modified: head/usr.bin/fold/fold.c
==============================================================================
--- head/usr.bin/fold/fold.c	Sat Nov  6 16:09:25 2010	(r214892)
+++ head/usr.bin/fold/fold.c	Sat Nov  6 17:48:46 2010	(r214893)
@@ -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;
 


More information about the svn-src-head mailing list