Subject: bin/31346: gzip should not give an error exit on large archives
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: seebs <seebs@vash.cel.plethora.net>
List: netbsd-bugs
Date: 09/19/2005 07:21:00
>Number: 31346
>Category: bin
>Synopsis: gzip erroneously indicates total failure on 4GB archives
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Sep 19 07:21:00 +0000 2005
>Originator: seebs
>Release: NetBSD 3.99.8
>Organization:
>Environment:
System: NetBSD vash.cel.plethora.net 3.99.8 NetBSD 3.99.8 (VASH) #0: Fri Sep 9 10:49:46 CDT 2005 seebs@vash.cel.plethora.net:/usr/src/sys/arch/i386/compile/VASH i386
Architecture: i386
Machine: i386
>Description:
The thoughtful note that gzip cannot record an input data size
over 4GB is useful. Returning an error status, however, is
catastrophic. Programs such as amanda will THROW AWAY DATA if they
think gzip failed! Error status should be indicated only when
compression has FAILED, not just because the compressed file has
a quirk common to pretty much every large gzip data file of the
past decade which will not prevent decompression.
>How-To-Repeat:
Use gzip on big data.
>Fix:
This patch adds a "maybe_gripe" feature which emits a warning message
without setting an exit status. It might be better to just not set
an exit status on any warning.
Index: gzip.c
===================================================================
RCS file: /cvsroot/src/usr.bin/gzip/gzip.c,v
retrieving revision 1.73
diff -c -r1.73 gzip.c
*** gzip.c 28 Aug 2005 10:17:50 -0000 1.73
--- gzip.c 19 Sep 2005 07:17:24 -0000
***************
*** 172,177 ****
--- 172,179 ----
static void maybe_errx(const char *fmt, ...)
__attribute__((__format__(__printf__, 1, 2)));
#endif
+ static void maybe_gripe(const char *fmt, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
static void maybe_warn(const char *fmt, ...)
__attribute__((__format__(__printf__, 1, 2)));
static void maybe_warnx(const char *fmt, ...)
***************
*** 366,371 ****
--- 368,386 ----
exit(exit_value);
}
+ /* maybe complain, but don't touch exit status */
+ void
+ maybe_gripe(const char *fmt, ...)
+ {
+ va_list ap;
+
+ if (qflag == 0) {
+ va_start(ap, fmt);
+ vwarn(fmt, ap);
+ va_end(ap);
+ }
+ }
+
/* maybe print a warning */
void
maybe_warn(const char *fmt, ...)
***************
*** 638,644 ****
if (i != 8)
maybe_err("snprintf");
if (in_tot > 0xffffffff)
! maybe_warn("input file size >= 4GB cannot be saved");
if (write(out, outbufp, i) != i) {
maybe_warn("write");
in_tot = -1;
--- 653,659 ----
if (i != 8)
maybe_err("snprintf");
if (in_tot > 0xffffffff)
! maybe_gripe("input file size >= 4GB cannot be saved");
if (write(out, outbufp, i) != i) {
maybe_warn("write");
in_tot = -1;