bug-gzip
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gzip > 1.3.? broken on NSK


From: Matthew Woehlke
Subject: gzip > 1.3.? broken on NSK
Date: Fri, 08 Dec 2006 14:46:05 -0600
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.8) Gecko/20061025 Thunderbird/1.5.0.8 Mnenhy/0.7.4.0

Ok, this took a while to track down, but I finally figured out why gzip 1.3.x is broken on NSK (not sure exactly when the problem started, but 1.3.5 was broken). 'man 2 read' says:

  nbytes    Specifies the number of bytes to read from the
            file associated with the filedes parameter.
            ...
            If the value of nbytes is greater than SSIZE_MAX,
            the read() function returns -1 and sets errno to
            [EINVAL].

gzip is using 64k in file_read (zip.c), but SSIZE_MAX is 53248 (52k). This causes gzip to be completely non-functional. We could limit the size to SSIZE_MAX, but I don't know how portable that is. (It doesn't seem to be on OSF, for one, although there *is* _POSIX_SSIZE_MAX. The problem with this is that it may not be defined without defining _POSIX_C_SOURCE which would be inelegant.) Alternatively, on all platforms I looked at, _POSIX_C_SOURCE (both existed, and) was 32k, so using that as a fixed value is probably OK (and obviously is no *less* safe than the current behavior).

Best is to check for SSIZE_MAX at configure time, and use 32k if it isn't found, and then *obey* it. Most platforms I looked at (actually, I think all the ones where 'man 2 read' worked) had the same stipulation that a read with size > SSIZE_MAX is not guaranteed to work, so failing to check this is a platform-agnostic bug.

I'm attaching the only obvious patch, but I'm not convinced this is the right way to do things (although it does seem to work; 'make check' passed):

--- ../gzip-1.3.7-orig/zip.c    2006-12-08 10:17:25.000000000 -0800
+++ zip.c       2006-12-08 12:36:36.000000000 -0800
@@ -124,6 +124,13 @@

     Assert(insize == 0, "inbuf not empty");

+#ifndef SSIZE_MAX
+# define SSIZE_MAX 32768
+#endif
+    if (size > SSIZE_MAX) {
+       size = SSIZE_MAX;
+    }
+
     len = read(ifd, buf, size);
     if (len == 0) return (int)len;
     if (len == (unsigned)-1) {


--
Matthew
HIPPOS wallow slightly in the MUDDY RIVER
What do you want to do next?
> WALLOW IN MUDDY RIVER
You join HIPPOS.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]