Page 1 of 1

another memory leak about reading corrupted pic, 6.7.9

Posted: 2012-09-27T03:11:02-07:00
by zhcn381
hi magick,

I noticed that there is another memory leak about freeing the memory allocated by ExceptionInfo. When image->exception is thrown, the following DestroyExceptionInfo will not be executed, thus lead to the leak. I've checked the src code of 6.2.8 and this is right there. Should be you guys' typo. :)

Code: Select all

Index: Image.cpp
===================================================================
--- Image.cpp   (revision 9453)
+++ Image.cpp   (working copy)
@@ -1603,9 +1603,9 @@
     }
   replaceImage( image );
   throwException( exceptionInfo );
+  (void) DestroyExceptionInfo( &exceptionInfo );
   if ( image )
     throwException( image->exception );
-  (void) DestroyExceptionInfo( &exceptionInfo );
 }
 
 // Read image of specified size into current object
@@ -1627,9 +1627,9 @@
                 blob_.length(), &exceptionInfo );
   replaceImage( image );
   throwException( exceptionInfo );
+  (void) DestroyExceptionInfo( &exceptionInfo );
   if ( image )
     throwException( image->exception );
-  (void) DestroyExceptionInfo( &exceptionInfo );
 }
 
 // Read image of specified size from in-memory BLOB
@@ -1702,9 +1702,9 @@
                      &exceptionInfo );
   replaceImage( image );
   throwException( exceptionInfo );
+  (void) DestroyExceptionInfo( &exceptionInfo );
   if ( image )
     throwException( image->exception );
-  (void) DestroyExceptionInfo( &exceptionInfo );
 }

By the way, there is another bug which I didn't figure out how to fix it. It's also a reading corrupted jpeg problem.

Code: Select all

Index: coders/jpeg.c + 638

  profile=BlobToStringInfo((const void *) NULL,length);
  if (profile == (StringInfo *) NULL)
    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
      image->filename);
  p=GetStringInfoDatum(profile);
  for (i=0; i < (ssize_t) GetStringInfoLength(profile); i++)
    *p++=(unsigned char) GetCharacter(jpeg_info);
when GetCharacter() ends early(FillInputBuffer() => JPEGErrorHandler => longjmp(error_manager->error_recovery,1)), the memory allocated by profile is not freed. Wish you guys could fix this bug soon. If necessary, I can provide the problem pic which may helps you guys reproduce the bug. Thx!

Re: another memory leak about reading corrupted pic, 6.7.9

Posted: 2012-09-27T04:21:19-07:00
by magick
Thanks for the problem report and patch.

Post a URL to your image so we can reproduce the JPEG memory leak. Its easy to fix but we will need to verify our patch against your corrupt image.

Re: another memory leak about reading corrupted pic, 6.7.9

Posted: 2012-09-27T08:09:24-07:00
by zhcn381
hi magick,

Thx for rapid response. Here is the corrupted jpeg file.

http://uploadingit.com/file/nanr4dqds9t ... edJPEG.jpg

Re: another memory leak about reading corrupted pic, 6.7.9

Posted: 2012-10-15T04:19:25-07:00
by broucaries
Could you post please cristy the svn id for the patch ? i need it for backport

Re: another memory leak about reading corrupted pic, 6.7.9

Posted: 2012-10-15T11:43:54-07:00
by magick
SVN revision 9473 includes the exception patch and adds support for mergeLayers. The relevant patch is:

Code: Select all

diff -r Magick++/lib/Image.cpp Magick++~/lib/Image.cpp
16a17,19
> #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
> #include <strings.h>
> #endif
1615,1619c1604
<   if ( image )
<     {
<       (void) DestroyExceptionInfo( &exceptionInfo );
<       throwException( image->exception );
<     }
---
>   replaceImage( image );
1620a1606,1607
>   if ( image )
>     throwException( image->exception );
1622d1608
<   replaceImage( image );
1644d1629
<   (void) DestroyExceptionInfo( &exceptionInfo );
1646a1632
>   (void) DestroyExceptionInfo( &exceptionInfo );
1719d1704
<   (void) DestroyExceptionInfo( &exceptionInfo );
1721a1707
>   (void) DestroyExceptionInfo( &exceptionInfo );
The relevant method should looks like this:

Code: Select all

void Magick::Image::read ( const std::string &imageSpec_ )
{
  options()->fileName( imageSpec_ );

  ExceptionInfo exceptionInfo;
  GetExceptionInfo( &exceptionInfo );
  MagickCore::Image* image =
    ReadImage( imageInfo(), &exceptionInfo );

  // Ensure that multiple image frames were not read.
  if ( image && image->next )
    {
      // Destroy any extra image frames
      MagickCore::Image* next = image->next;
      image->next = 0;
      next->previous = 0;
      DestroyImageList( next );

    }
  if ( image )
    {
      (void) DestroyExceptionInfo( &exceptionInfo );
      throwException( image->exception );
    }
  throwException( exceptionInfo );
  (void) DestroyExceptionInfo( &exceptionInfo );
  replaceImage( image );
}