Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Apr 1999 20:29:16 -0500 (CDT)
From:      dkelly@hiwaay.net
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/11141: wc can't count high enough
Message-ID:  <199904150129.UAA89851@nospam.hiwaay.net>

next in thread | raw e-mail | index | archive | help

>Number:         11141
>Category:       bin
>Synopsis:       u_long is not big enough
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 14 18:40:00 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     David Kelly
>Release:        FreeBSD 3.1-STABLE i386
>Organization:
none
>Environment:

	

>Description:

Today I had a file, tape.tar.gz, that was 400M in size and curious as to
how much space it would take to extract. Was happy when the following
indicated only 4G was needed:

	% gunzip -c tape.tar.gz | wc -c

Then I proceeded to fill the remaining 6G of my fs attempting to extract.
Thinking about it, guessed a 32 bit counter overflowed and I really have
about 8G of data. Was also showing off FreeBSD and said, "Oh, forgot to mention
200M of stuff on your HD is the *complete* source to this system. Lets
go look at the source to wc." Their jaws hit the floor.


>How-To-Repeat:

% dd if=/dev/zero bs=1024k count=6000 | /usr/bin/wc -c
6000+0 records in
6000+0 records out
6291456000 bytes transferred in 1390.680056 secs (4524014 bytes/sec)
 1996488704
%

With patches (enclosed) applied:

% dd if=/dev/zero bs=1024k count=6000 | ./wc -c
6000+0 records in
6000+0 records out
6291456000 bytes transferred in 1115.535951 secs (5639851 bytes/sec)
 6291456000
%

% dc
1024 1024 * 6000 * p
6291456000
6291456000 1024 1024 * 1024 * 4 * - p
1996488704
q
%

>Fix:

Notice I also changed some %ld's into %qu's.

Thought about changing the 7 in %7qu to something bigger but decided
that might break some scripts. If really big numbers are output it
will break those scripts anyhow. So I dunno. Leave the output spaced
over with the %7qu for tradition's sake?
	
% diff -c wc.c wc.c.orig
*** wc.c	Wed Apr 14 19:52:40 1999
--- wc.c.orig	Mon Aug 25 01:44:59 1997
***************
*** 58,64 ****
  #include <string.h>
  #include <unistd.h>
  
! quad_t tlinect, twordct, tcharct;
  int doline, doword, dochar;
  
  int cnt __P((char *));
--- 58,64 ----
  #include <string.h>
  #include <unistd.h>
  
! u_long tlinect, twordct, tcharct;
  int doline, doword, dochar;
  
  int cnt __P((char *));
***************
*** 114,124 ****
  
  	if (total > 1) {
  		if (doline)
! 			(void)printf(" %7qu", tlinect);
  		if (doword)
! 			(void)printf(" %7qu", twordct);
  		if (dochar)
! 			(void)printf(" %7qu", tcharct);
  		(void)printf(" total\n");
  	}
  	exit(errors == 0 ? 0 : 1);
--- 114,124 ----
  
  	if (total > 1) {
  		if (doline)
! 			(void)printf(" %7ld", tlinect);
  		if (doword)
! 			(void)printf(" %7ld", twordct);
  		if (dochar)
! 			(void)printf(" %7ld", tcharct);
  		(void)printf(" total\n");
  	}
  	exit(errors == 0 ? 0 : 1);
***************
*** 131,137 ****
  	register u_char *p, ch;
  	register short gotsp;
  	register int len;
! 	register quad_t linect, wordct, charct;
  	struct stat sb;
  	int fd;
  	u_char buf[MAXBSIZE];
--- 131,137 ----
  	register u_char *p, ch;
  	register short gotsp;
  	register int len;
! 	register u_long linect, wordct, charct;
  	struct stat sb;
  	int fd;
  	u_char buf[MAXBSIZE];
***************
*** 165,174 ****
  						++linect;
  			}
  			tlinect += linect;
! 			(void)printf(" %7qu", linect);
  			if (dochar) {
  				tcharct += charct;
! 				(void)printf(" %7qu", charct);
  			}
  			(void)close(fd);
  			return (0);
--- 165,174 ----
  						++linect;
  			}
  			tlinect += linect;
! 			(void)printf(" %7lu", linect);
  			if (dochar) {
  				tcharct += charct;
! 				(void)printf(" %7lu", charct);
  			}
  			(void)close(fd);
  			return (0);
***************
*** 219,233 ****
  	}
  	if (doline) {
  		tlinect += linect;
! 		(void)printf(" %7qu", linect);
  	}
  	if (doword) {
  		twordct += wordct;
! 		(void)printf(" %7qu", wordct);
  	}
  	if (dochar) {
  		tcharct += charct;
! 		(void)printf(" %7qu", charct);
  	}
  	(void)close(fd);
  	return (0);
--- 219,233 ----
  	}
  	if (doline) {
  		tlinect += linect;
! 		(void)printf(" %7lu", linect);
  	}
  	if (doword) {
  		twordct += wordct;
! 		(void)printf(" %7lu", wordct);
  	}
  	if (dochar) {
  		tcharct += charct;
! 		(void)printf(" %7lu", charct);
  	}
  	(void)close(fd);
  	return (0);

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904150129.UAA89851>