ANOTHER case where compress gets destructive on interrupt

Mark Brader msb at sq.uucp
Fri Apr 15 22:07:01 AEST 1988


Weird.  One day I find a bug in compress, and the next day we get a
news posting about another form of it.

Rick Perry writes:
> ... while using 'zcat x.Z', if you interrupt it,
> it removes the file 'x'.

It turns out that no matter whether you're using it in its identity
as zcat, compress, or uncompress, in each case there exists a time
window when an interrupt will leave you with both x and x.Z removed.
For instance, if you "uncompress x.Z" and interrupt just as it's finishing...

This is because the interrupt handler is always enabled and too simple:
it just assumes that ofname[] contains the name of a file it can remove.

Below is my fix.  It covers Rick's bug too, so you don't have to install
his fix as well.  I also amended the rather optimistic message in the SIGSEGV
handler, as you will see.

We have compress version 4.0.  As we don't use RCS here, I haven't
adjusted the RCS id stuff.

Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb, msb at sq.com
	"I'm a little worried about the bug-eater," she said.  "We're embedded
	in bugs, have you noticed?"		-- Niven, "The Integral Trees"

*** /tmp/da3150	Fri Apr 15 08:03:05 1988
--- compress.c	Fri Apr 15 08:02:31 1988
***************
*** 138,143 ****
--- 138,147 ----
   *		James A. Woods		(decvax!ihnp4!ames!jaw)
   *		Joe Orost		(decvax!vax135!petsd!joe)
   *
+  *	Mark Brader (sq!msb) added checking so that we don't end up
+  *	with both input and output files removed on interrupts.
+  *	This is not in the RCS numbering.
+  *
   * $Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $
   * $Log:	compress.c,v $
   * Revision 4.0  85/07/30  12:50:00  joe
***************
*** 357,362 ****
--- 361,368 ----
  
  int force = 0;
  char ofname [100];
+ int oktozap = 0;	/* true if unlink(ofname) won't lose data */
+ 
  #ifdef DEBUG
  int verbose = 0;
  #endif /* DEBUG */
***************
*** 625,630 ****
--- 631,637 ----
  		}
  	    }
  	    if(zcat_flg == 0) {		/* Open output file */
+ 		oktozap = 1;
  		if (freopen(ofname, "w", stdout) == NULL) {
  		    perror(ofname);
  		    continue;
***************
*** 1277,1282 ****
--- 1284,1290 ----
      time_t timep[2];
  
      fclose(stdout);
+     oktozap = 0;
      if (stat(ifname, &statbuf)) {		/* Get stat on input file */
  	perror(ifname);
  	return;
***************
*** 1334,1340 ****
  
  onintr ( )
  {
!     unlink ( ofname );
      exit ( 1 );
  }
  
--- 1342,1349 ----
  
  onintr ( )
  {
!     if (oktozap)
! 	unlink ( ofname );
      exit ( 1 );
  }
  
***************
*** 1341,1348 ****
  oops ( )	/* wild pointer -- assume bad input */
  {
      if ( do_decomp == 1 ) 
!     	fprintf ( stderr, "uncompress: corrupt input\n" );
!     unlink ( ofname );
      exit ( 1 );
  }
  
--- 1350,1359 ----
  oops ( )	/* wild pointer -- assume bad input */
  {
      if ( do_decomp == 1 ) 
!     	fprintf ( stderr,
! 	    "uncompress: segmentation violation - probably corrupt input\n" );
!     if (oktozap)
! 	unlink ( ofname );
      exit ( 1 );
  }
  



More information about the Comp.sources.bugs mailing list