Hi,

The ReadOnePNGImage() function contains this code:

  QuantumInfo
    *quantum_info;
...
  quantum_info = NULL;
  if (setjmp(ping->jmpbuf))
    {
      /*
        PNG image is corrupt.
      */
...
      if (quantum_info != (QuantumInfo *) NULL)
        quantum_info = DestroyQuantumInfo(quantum_info);
...
      return(GetFirstImageInList(image));
    }
...
  /*
    Convert PNG pixels to pixel packets.
  */
  quantum_info=AcquireQuantumInfo(image_info,image);
  /* use it, possibly call longjmp() ... */
  quantum_info=DestroyQuantumInfo(quantum_info);

And here is a problem, because the longjmp() manual page says:

       The values of automatic variables  are  unspecified  after  a  call  to
       longjmp() if they meet all the following criteria:

       o  they are local to the function that made the corresponding setjmp(3)
          call;

       o  their  values  are  changed  between  the  calls  to  setjmp(3)  and
          longjmp(); and

       o  they are not declared as volatile.

For quantum_info, all three conditions are true. And indeed, some gcc
versions decide to cache it in a register at the time when setjmp() is
called. So, when longjmp() restores that context, it also restores the
register where quantum_info is held (to NULL). Thus,
DestroyQuantumInfo is not called, and there is a memory leak
reproducible on linux, e.g., by passing an incompletely downloaded png
file to BlobToImage(). The same consideration applies to two more
variables.

So, for a quick fix, I propose to change three declarations, as follows:

  Image
    * volatile image;

  QuantumInfo
    * volatile quantum_info;

  unsigned char
    * volatile png_pixels;



-- 
Alexander E. Patrakov
_______________________________________________
Magick-developers mailing list
Magick-developers@imagemagick.org
http://studio.imagemagick.org/mailman/listinfo/magick-developers

Reply via email to