Subject: bin/32070: gzip -vt bugs and endless loop on corrupt .bz2
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Onno van der Linden <o.vd.linden@quicknet.nl>
List: netbsd-bugs
Date: 11/14/2005 08:18:00
>Number:         32070
>Category:       bin
>Synopsis:       wrong output for gzip -vt and endless loop on corrupt .bz2 file
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov 14 08:18:00 +0000 2005
>Originator:     Onno van der Linden
>Release:        NetBSD 3.99.11
>Organization:
	
>Environment:
	
	
System: NetBSD sheep 3.99.11 NetBSD 3.99.11 (SHEEP) #0: Sat Nov 12 11:33:05 MET 2005 onno@sheep:/usr/src/sys/arch/i386/compile/SHEEP i386
Architecture: i386
Machine: i386
>Description:
	1) gzip -vt just prints the contents of a .Z file
	2) gzip -vt will print OK even if the .gz file is corrupt
	3) gzip -vt prints nothing with a .bz2 file
	4) gzip can loop endlessly with a corrupt .bz2 file
>How-To-Repeat:
	1) gzip -vt on any file that's been compressed with compress(1)
	2) delete some characters from a valid .gz file with vi and
	   run gzip -vt
	3) gzip -vt on any file that's been compressed with bzip2(1)
	4) don't know how I created that corrupt file :-(
	   BZ2_bzDecompress() kept returning -1 forever

>Fix:
diff -c2N /usr/src/usr.bin/gzip/gzip.c ./gzip.c
*** /usr/src/usr.bin/gzip/gzip.c	Tue Sep 20 21:13:06 2005
--- ./gzip.c	Sun Nov 13 16:26:08 2005
***************
*** 730,737 ****
  
  			if (in_size == -1) {
- #ifndef SMALL
- 				if (tflag && vflag)
- 					print_test(filename, 0);
- #endif
  				maybe_warn("failed to read stdin");
  				goto stop_and_fail;
--- 730,733 ----
***************
*** 985,989 ****
  		continue;
  stop_and_fail:
! 		out_tot = 1;
  stop:
  		break;
--- 981,985 ----
  		continue;
  stop_and_fail:
! 		out_tot = -1;
  stop:
  		break;
***************
*** 992,1000 ****
  		inflateEnd(&z);
  
- #ifndef SMALL
- 	if (tflag && vflag)
- 		print_test(filename, out_tot != -1);
- #endif
- 
  	free(inbufp);
  out1:
--- 988,991 ----
***************
*** 1617,1620 ****
--- 1608,1613 ----
          if (vflag && !tflag && usize != -1 && gsize != -1)
  		print_verbage(NULL, NULL, usize, gsize);
+ 	if (vflag && tflag)
+ 		print_test("(stdin)", usize != -1);
  #endif 
  
***************
*** 1732,1735 ****
--- 1725,1730 ----
  	if (dflag) {
  		usize = file_uncompress(file, outfile, sizeof(outfile));
+ 		if (vflag && tflag)
+ 			print_test(file, usize != -1);
  		if (usize == -1)
  			return;
diff -c2N /usr/src/usr.bin/gzip/unbzip2.c ./unbzip2.c
*** /usr/src/usr.bin/gzip/unbzip2.c	Thu Sep 15 16:37:49 2005
--- ./unbzip2.c	Sun Nov 13 16:23:48 2005
***************
*** 34,38 ****
  		*bytes_in = prelen;
  
! 	while (ret != BZ_STREAM_END) {
  	        if (bzs.avail_in == 0 && !end_of_file) {
  			ssize_t	n;
--- 34,38 ----
  		*bytes_in = prelen;
  
! 	while (ret >= BZ_OK && ret != BZ_STREAM_END) {
  	        if (bzs.avail_in == 0 && !end_of_file) {
  			ssize_t	n;
diff -c2N /usr/src/usr.bin/gzip/zuncompress.c ./zuncompress.c
*** /usr/src/usr.bin/gzip/zuncompress.c	Fri Sep  3 20:45:09 2004
--- ./zuncompress.c	Tue Nov  8 16:48:17 2005
***************
*** 147,151 ****
  
  	while ((bin = fread(buf, 1, sizeof(buf), in)) != 0) {
! 		if (fwrite(buf, 1, bin, out) != bin) {
  			free(buf);
  			return -1;
--- 147,151 ----
  
  	while ((bin = fread(buf, 1, sizeof(buf), in)) != 0) {
! 		if (tflag == 0 && fwrite(buf, 1, bin, out) != bin) {
  			free(buf);
  			return -1;


----- End forwarded message -----

>Unformatted: