Small bug in zlib module

Greg Chapman glc at well.com
Wed Jun 7 15:16:06 EDT 2000


On 6 Jun 2000 16:42:06 -0000, Peter Schneider-Kamp wrote:
> Greg Chapman wrote:
> >
> > Using Python 1.5.2 (under Windows 98), this script causes python to
> > enter a loop in which it progressively allocates larger and larger
> > blocks of memory:
> >
> >   import zlib
> >   s = zlib.decompress("")
> > I assume PyZlib_decompress should have a check for an empty input
> > string and (if found) should generate an appropriate exception.
> >
> On the current CVS version it immediately (as far as I can see without
> looping) returns with an error.
>

I just checked ver. 2.32 (which seems to be the latest in the SourceForge
web CVS repository).  If the check you're referring to is this:

  if (r_strlen <= 0)
      r_strlen = 1;

that doesn't catch the condition I described.  Instead, you need to check
the "length" variable, which has the length of the input string (and I don't
see such a check; perhaps I missed it?).  Anyway, as it turns out, simply
checking for an empty input string is not sufficient.  The following causes
Python to enter the same memory allocation loop:

  import zlib
  s = zlib.decompress("\010")

I received a reply from eito which I believe correctly diagnoses the problem
and solution (this reply apparently did not go to the list):

On Tue, 6 Jun 2000 13:07:58 -0700, eito wrote:
> I think because, in zlib module, when it gets Z_BUF_ERROR, it does not
> check for the cause of the error. I don't know if the author of this
> module intentionally left the checking. (the same is true in the
> latest CVS version) Because it will return an error (MemoryError)
> anyway.
>
>
>   [from zlib.h (version 1.13)]
>   "Inflate() returns ... Z_BUF_ERROR if no progress is possible or
>    if there was not enough room in the output buffer when Z_FINISH
>    is used."
>
>
> The zlib's description is not so clear to me, but I modified zlib
> module anyway... The following patch (in the end of this e-mail) for
> zlibmodule.c (of version 1.5.2) should fix your problem. This patch
> checks for the output buffer, if the inflate() gets Z_BUF_ERROR. And
> if there is a room in the output buffer, it return an error.
> Otherwise, it goes to case(Z_OK), which tries to allocate more output
> buffer.
>

Eito's patch (see below) looks OK to me, provided that the test avail_out >
0 is a reliable way to distinguish between the two kinds of Z_BUF_ERROR
(i.e., cases where no progress is possible and cases where progress is
possible, but a bigger output buffer is needed).

By the way, I apologize for posting this to the main list.  I didn't realize
until yesterday that www.python.org has a bug list to handle this sort of
report.

Greg Chapman


-----zlibmodule.patch-----
*** zlibmodule.c.orig   Tue Jun  6 09:42:12 2000
--- zlibmodule.c        Tue Jun  6 09:53:12 2000
***************
*** 222,227 ****
--- 222,240 ----
          case(Z_STREAM_END):
            break;
        case(Z_BUF_ERROR):
+             /*
+              * If there is at least 1 byte of room in zst.next_out
+              * and get this error, I assume that it means zlib cannot
+              * process inflate.
+              */
+             if (0 < zst.avail_out)
+             {
+               PyErr_Format(ZlibError, "Error %i while decompressing data",
+                            err);
+               inflateEnd(&zst);
+               Py_DECREF(result_str);
+               return NULL;
+             }
          case(Z_OK):
            /* need more memory */
            if (_PyString_Resize(&result_str, r_strlen << 1) == -1)
-----zlibmodule.patch-----





More information about the Python-list mailing list