aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/fold/fold.c
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2010-11-06 17:48:46 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2010-11-06 17:48:46 +0000
commit76423301d361678d6a8ded370814bad1c3b00421 (patch)
tree0b01586ecbae09c5376a3e58f3ddc8f788572d55 /usr.bin/fold/fold.c
parent9283118f01acfe5ca731db462d9df23fe0b794f8 (diff)
downloadsrc-76423301d361678d6a8ded370814bad1c3b00421.tar.gz
src-76423301d361678d6a8ded370814bad1c3b00421.zip
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@blazingdot.com> Tested by: Marcus Reid <marcus@blazingdot.com> MFC after: 3 days
Notes
Notes: svn path=/head/; revision=214893
Diffstat (limited to 'usr.bin/fold/fold.c')
-rw-r--r--usr.bin/fold/fold.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/usr.bin/fold/fold.c b/usr.bin/fold/fold.c
index 59d8fc59adfd..d4255fc70ebd 100644
--- a/usr.bin/fold/fold.c
+++ b/usr.bin/fold/fold.c
@@ -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;