Subject: bin/23836: cmp doesn't handle skip parameters as documented
To: None <gnats-bugs@gnats.netbsd.org>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 12/22/2003 02:40:09
>Number:         23836
>Category:       bin
>Synopsis:       cmp doesn't handle skip parameters as documented
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Dec 22 02:41:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Christian Biere
>Release:        NetBSD 1.6ZG
>Organization:
>Environment:
System: NetBSD cyclonus 1.6ZG NetBSD 1.6ZG (STARSCREAM) #0: Tue Dec 16 17:11:50 CET 2003 bin@cyclonus:/usr/build/arch/i386/compile/STARSCREAM i386
Architecture: i386
Machine: i386
>Description:

The manpage of cmp(1) mentions that the parameters 'skip1' and 'skip2' maybe
given in decimal, hexadecimal or octal form. This isn't true. The code
handles and expects only decimal numbers. The code also doesn't perform any
error checking for these parameters so that you can easily pass obviously
wrong parameters without noticing it. The latter isn't strictly a bug - I
know. However, I see absolutely no reason for not adding it.

>How-To-Repeat:

$ echo 0123456789abcdef > a
$ echo abcdef > b
$ cmp a b '0xa' || echo MISMATCH
a b differ: char 1, line 1
MISMATCH

>Fix:

Index: cmp.c
===================================================================
RCS file: /cvsroot/src/usr.bin/cmp/cmp.c,v
retrieving revision 1.13
diff -u -u -r1.13 cmp.c
--- cmp.c	2003/08/07 11:13:22	1.13
+++ cmp.c	2003/12/22 02:23:20
@@ -47,6 +47,7 @@
 #include <sys/stat.h>
 
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -67,7 +68,7 @@
 	char *argv[];
 {
 	struct stat sb1, sb2;
-	off_t skip1, skip2;
+	off_t skip1 = 0, skip2 = 0;
 	int ch, fd1, fd2, special;
 	char *file1, *file2;
 
@@ -120,8 +121,20 @@
 		exit(ERR_EXIT);
 	}
 
-	skip1 = argc > 2 ? strtoq(argv[2], NULL, 10) : 0;
-	skip2 = argc == 4 ? strtoq(argv[3], NULL, 10) : 0;
+	if (argc > 2) {
+		char *ep;
+
+		errno = 0;
+		skip1 = strtoq(argv[2], &ep, 0);
+		if (errno || ep == argv[2])
+			usage();
+
+		if (argc == 4) {
+			skip2 = strtoq(argv[3], &ep, 0);
+			if (errno || ep == argv[3])
+				usage();
+		}
+	}
 
 	if (!special) {
 		if (fstat(fd1, &sb1))
>Release-Note:
>Audit-Trail:
>Unformatted: