Ignore:
Timestamp:
04/12/12 10:16:21 (13 months ago)
Author:
glennrp
Message:

Always unlock the semaphore on return or error return from the PNG codec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ImageMagick/trunk/coders/png.c

    r7219 r7458  
    585585#endif 
    586586 
    587 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     587#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    588588static SemaphoreInfo 
    589589  *ping_semaphore = (SemaphoreInfo *) NULL; 
     
    18091809 
    18101810static int 
    1811 Magick_png_read_raw_profile(Image *image, const ImageInfo *image_info, 
    1812    png_textp text,int ii,ExceptionInfo *exception) 
     1811Magick_png_read_raw_profile(png_struct *ping,Image *image, 
     1812   const ImageInfo *image_info, png_textp text,int ii,ExceptionInfo *exception) 
    18131813{ 
    18141814  register ssize_t 
     
    18561856  if (length == 0) 
    18571857  { 
    1858     (void) ThrowMagickException(exception,GetMagickModule(), 
    1859       CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length"); 
     1858    png_warning(ping,"invalid profile length"); 
    18601859    return(MagickFalse); 
    18611860  } 
     
    18651864  if (profile == (StringInfo *) NULL) 
    18661865  { 
    1867     (void) ThrowMagickException(exception,GetMagickModule(), 
    1868       ResourceLimitError,"MemoryAllocationFailed","`%s'", 
    1869       "unable to copy profile"); 
     1866    png_warning(ping, "unable to copy profile"); 
    18701867    return(MagickFalse); 
    18711868  } 
     
    18811878      if (*sp == '\0') 
    18821879        { 
    1883           (void) ThrowMagickException(exception,GetMagickModule(), 
    1884             CoderWarning,"UnableToCopyProfile","`%s'","ran out of data"); 
     1880          png_warning(ping, "ran out of profile data"); 
    18851881          profile=DestroyStringInfo(profile); 
    18861882          return(MagickFalse); 
     
    20862082  logging=LogMagickEvent(CoderEvent,GetMagickModule(), 
    20872083    "  Enter ReadOnePNGImage()"); 
    2088  
    2089 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    2090   LockSemaphoreInfo(ping_semaphore); 
    2091 #endif 
    20922084 
    20932085#if (PNG_LIBPNG_VER < 10200) 
     
    21662158      */ 
    21672159      png_destroy_read_struct(&ping,&ping_info,&end_info); 
    2168 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     2160 
     2161#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    21692162      UnlockSemaphoreInfo(ping_semaphore); 
    21702163#endif 
     2164 
     2165      if (ping_pixels != (unsigned char *) NULL) 
     2166        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
     2167 
    21712168      if (logging != MagickFalse) 
    21722169        (void) LogMagickEvent(CoderEvent,GetMagickModule(), 
     
    21812178      return(GetFirstImageInList(image)); 
    21822179    } 
     2180 
     2181  /* {  For navigation to end of SETJMP-protected block.  Within this 
     2182   *    block, use png_error() instead of Throwing an Exception, to ensure 
     2183   *    that libpng is able to clean up, and that the semaphore is unlocked. 
     2184   */ 
     2185 
     2186#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
     2187  LockSemaphoreInfo(ping_semaphore); 
     2188#endif 
     2189 
    21832190  /* 
    21842191    Prepare PNG for reading. 
     
    23152322          profile=BlobToStringInfo(info,profile_length); 
    23162323          if (profile == (StringInfo *) NULL) 
    2317           { 
    2318             (void) ThrowMagickException(exception,GetMagickModule(), 
    2319               ResourceLimitError,"MemoryAllocationFailed","`%s'", 
    2320               "unable to copy profile"); 
    2321             return((Image *) NULL); 
    2322           } 
    2323           SetStringInfoDatum(profile,(const unsigned char *) info); 
    2324           (void) SetImageProfile(image,"icc",profile,exception); 
    2325           profile=DestroyStringInfo(profile); 
     2324            { 
     2325              png_warning(ping, "ICC profile is NULL"); 
     2326              profile=DestroyStringInfo(profile); 
     2327            } 
     2328          else 
     2329            { 
     2330              (void) SetImageProfile(image,"icc",profile,exception); 
     2331              profile=DestroyStringInfo(profile); 
     2332            } 
    23262333      } 
    23272334    } 
     
    24702477 
    24712478              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS)) 
     2479              { 
    24722480                if (mng_info->global_trns_length) 
    24732481                  { 
    2474                     if (mng_info->global_trns_length > 
    2475                         mng_info->global_plte_length) 
    2476                       (void) ThrowMagickException(exception, 
    2477                         GetMagickModule(),CoderError, 
    2478                         "global tRNS has more entries than global PLTE", 
    2479                         "`%s'",image_info->filename); 
    2480                     png_set_tRNS(ping,ping_info,mng_info->global_trns, 
    2481                       (int) mng_info->global_trns_length,NULL); 
     2482                    png_warning(ping, 
     2483                      "global tRNS has more entries than global PLTE"); 
    24822484                  } 
     2485                else 
     2486                  { 
     2487                     png_set_tRNS(ping,ping_info,mng_info->global_trns, 
     2488                       (int) mng_info->global_trns_length,NULL); 
     2489                  } 
     2490               } 
    24832491#ifdef PNG_READ_bKGD_SUPPORTED 
    24842492              if ( 
     
    25152523                } 
    25162524              else 
    2517                 (void) ThrowMagickException(exception,GetMagickModule(), 
    2518                   CoderError,"No global PLTE in file","`%s'", 
    2519                   image_info->filename); 
     2525                png_error(ping,"No global PLTE in file"); 
    25202526            } 
    25212527        } 
     
    27322738      */ 
    27332739      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) 
    2734         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 
     2740        png_error(ping,"Memory allocation failed"); 
    27352741 
    27362742      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) 
     
    28202826          mng_info->scenes_found-1); 
    28212827      png_destroy_read_struct(&ping,&ping_info,&end_info); 
    2822 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     2828 
     2829#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    28232830      UnlockSemaphoreInfo(ping_semaphore); 
    28242831#endif 
     2832 
    28252833      if (logging != MagickFalse) 
    28262834        (void) LogMagickEvent(CoderEvent,GetMagickModule(), 
     
    28432851 
    28442852  if (ping_pixels == (unsigned char *) NULL) 
    2845     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 
     2853    png_error(ping,"Memory allocation failed"); 
    28462854 
    28472855  if (logging != MagickFalse) 
     
    28512859    Convert PNG pixels to pixel packets. 
    28522860  */ 
    2853   if (setjmp(png_jmpbuf(ping))) 
    2854     { 
    2855       /* 
    2856         PNG image is corrupt. 
    2857       */ 
    2858       png_destroy_read_struct(&ping,&ping_info,&end_info); 
    2859 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    2860       UnlockSemaphoreInfo(ping_semaphore); 
    2861 #endif 
    2862       if (quantum_info != (QuantumInfo *) NULL) 
    2863         quantum_info = DestroyQuantumInfo(quantum_info); 
    2864  
    2865       if (ping_pixels != (unsigned char *) NULL) 
    2866         ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
    2867  
    2868       if (logging != MagickFalse) 
    2869         (void) LogMagickEvent(CoderEvent,GetMagickModule(), 
    2870           "  exit ReadOnePNGImage() with error."); 
    2871  
    2872       if (image != (Image *) NULL) 
    2873         { 
    2874           InheritException(exception,exception); 
    2875           image->columns=0; 
    2876         } 
    2877  
    2878       return(GetFirstImageInList(image)); 
    2879     } 
    2880  
    28812861  quantum_info=AcquireQuantumInfo(image_info,image); 
    28822862 
    28832863  if (quantum_info == (QuantumInfo *) NULL) 
    2884     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 
     2864     png_error(ping,"Failed to allocate quantum_info"); 
    28852865 
    28862866  { 
     
    30273007 
    30283008      if (quantum_scanline == (Quantum *) NULL) 
    3029         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 
     3009        png_error(ping,"Memory allocation failed"); 
    30303010 
    30313011      for (y=0; y < (ssize_t) image->rows; y++) 
     
    32543234      image->colors=2; 
    32553235      (void) SetImageBackgroundColor(image,exception); 
    3256 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     3236#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    32573237      UnlockSemaphoreInfo(ping_semaphore); 
    32583238#endif 
     
    33713351        if (memcmp(text[i].key, "Raw profile type ",17) == 0) 
    33723352          { 
    3373             (void) Magick_png_read_raw_profile(image,image_info,text,(int) i, 
    3374               exception); 
     3353            (void) Magick_png_read_raw_profile(ping,image,image_info,text, 
     3354               (int) i,exception); 
    33753355            num_raw_profiles++; 
    33763356          } 
     
    33863366            if (value == (char *) NULL) 
    33873367              { 
    3388                 (void) ThrowMagickException(exception,GetMagickModule(), 
    3389                   ResourceLimitError,"MemoryAllocationFailed","`%s'", 
    3390                   image->filename); 
     3368                png_error(ping,"Memory allocation failed"); 
    33913369                break; 
    33923370              } 
     
    34413419        { 
    34423420          if (mng_info->ob[object_id] == (MngBuffer *) NULL) 
    3443             (void) ThrowMagickException(exception,GetMagickModule(), 
    3444               ResourceLimitError,"MemoryAllocationFailed","`%s'", 
    3445               image->filename); 
     3421             png_error(ping,"Memory allocation failed"); 
    34463422 
    34473423          if (mng_info->ob[object_id]->frozen) 
    3448             (void) ThrowMagickException(exception,GetMagickModule(), 
    3449               ResourceLimitError,"Cannot overwrite frozen MNG object buffer", 
    3450               "`%s'",image->filename); 
     3424            png_error(ping,"Cannot overwrite frozen MNG object buffer"); 
    34513425        } 
    34523426 
     
    34653439 
    34663440          else 
    3467             (void) ThrowMagickException(exception,GetMagickModule(), 
    3468               ResourceLimitError,"Cloning image for object buffer failed", 
    3469               "`%s'",image->filename); 
     3441            png_error(ping, "Cloning image for object buffer failed"); 
    34703442 
    34713443          if (ping_width > 250000L || ping_height > 250000L) 
     
    36223594 
    36233595  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
    3624 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    3625   UnlockSemaphoreInfo(ping_semaphore); 
    3626 #endif 
    36273596 
    36283597  if (logging != MagickFalse) 
    36293598    (void) LogMagickEvent(CoderEvent,GetMagickModule(), 
    36303599      "  exit ReadOnePNGImage()"); 
     3600 
     3601#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
     3602  UnlockSemaphoreInfo(ping_semaphore); 
     3603#endif 
     3604 
     3605  /* }  for navigation to beginning of SETJMP-protected block, revert to 
     3606   *    Throwing an Exception when an error occurs. 
     3607   */ 
    36313608 
    36323609  return(image); 
     
    49944971              { 
    49954972                /* 
    4996                   Instead ofsuing a warning we should allocate a larger 
     4973                  Instead of using a warning we should allocate a larger 
    49974974                  MngInfo structure and continue. 
    49984975                */ 
     
    72087185  (void) RegisterMagickInfo(entry); 
    72097186 
    7210 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     7187#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    72117188  ping_semaphore=AllocateSemaphoreInfo(); 
    72127189#endif 
     
    72437220  (void) UnregisterMagickInfo("JNG"); 
    72447221 
    7245 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     7222#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    72467223  if (ping_semaphore != (SemaphoreInfo *) NULL) 
    72477224    DestroySemaphoreInfo(&ping_semaphore); 
     
    75927569  if (image_info == (ImageInfo *) NULL) 
    75937570     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); 
    7594  
    7595 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    7596   LockSemaphoreInfo(ping_semaphore); 
    7597 #endif 
    75987571 
    75997572  /* Initialize some stuff */ 
     
    88758848          "Cannot write PNG8 or color-type 3; colormap is NULL", 
    88768849          "`%s'",IMimage->filename); 
    8877 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    8878       UnlockSemaphoreInfo(ping_semaphore); 
    8879 #endif 
    88808850      return(MagickFalse); 
    88818851    } 
     
    89208890#endif 
    89218891      png_destroy_write_struct(&ping,&ping_info); 
    8922 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
     8892#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
    89238893      UnlockSemaphoreInfo(ping_semaphore); 
    89248894#endif 
     8895 
     8896      if (ping_pixels != (unsigned char *) NULL) 
     8897        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
     8898 
     8899      if (quantum_info != (QuantumInfo *) NULL) 
     8900        quantum_info=DestroyQuantumInfo(quantum_info); 
     8901 
    89258902      if (ping_have_blob != MagickFalse) 
    89268903          (void) CloseBlob(image); 
     
    89298906      return(MagickFalse); 
    89308907    } 
     8908 
     8909  /* {  For navigation to end of SETJMP-protected block.  Within this 
     8910   *    block, use png_error() instead of Throwing an Exception, to ensure 
     8911   *    that libpng is able to clean up, and that the semaphore is unlocked. 
     8912   */ 
     8913 
     8914#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
     8915  LockSemaphoreInfo(ping_semaphore); 
     8916#endif 
     8917 
    89318918  /* 
    89328919    Prepare PNG for writing. 
     
    92839270           { 
    92849271              /* DO SOMETHING */ 
    9285               (void) ThrowMagickException(exception, 
    9286                  GetMagickModule(),CoderError, 
    9287                 "image has 0 colors", "`%s'",""); 
     9272                png_error(ping,"image has 0 colors"); 
    92889273           } 
    92899274 
     
    1031110296 
    1031210297  if (ping_pixels == (unsigned char *) NULL) 
    10313     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 
     10298    png_error(ping,"Allocation of memory for pixels failed"); 
    1031410299 
    1031510300  /* 
    1031610301    Initialize image scanlines. 
    1031710302  */ 
    10318   if (setjmp(png_jmpbuf(ping))) 
    10319     { 
    10320       /* 
    10321         PNG write failed. 
    10322       */ 
    10323 #ifdef PNG_DEBUG 
    10324      if (image_info->verbose) 
    10325         (void) printf("PNG write has failed.\n"); 
    10326 #endif 
    10327       png_destroy_write_struct(&ping,&ping_info); 
    10328       if (quantum_info != (QuantumInfo *) NULL) 
    10329         quantum_info=DestroyQuantumInfo(quantum_info); 
    10330       if (ping_pixels != (unsigned char *) NULL) 
    10331         ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
    10332 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    10333       UnlockSemaphoreInfo(ping_semaphore); 
    10334 #endif 
    10335       if (ping_have_blob != MagickFalse) 
    10336           (void) CloseBlob(image); 
    10337       image_info=DestroyImageInfo(image_info); 
    10338       image=DestroyImage(image); 
    10339       return(MagickFalse); 
    10340     } 
    1034110303  quantum_info=AcquireQuantumInfo(image_info,image); 
    1034210304  if (quantum_info == (QuantumInfo *) NULL) 
    10343     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 
     10305    png_error(ping,"Memory allocation for quantum_info failed"); 
    1034410306  quantum_info->format=UndefinedQuantumFormat; 
    1034510307  quantum_info->depth=image_depth; 
     
    1075710719  if (mng_info->write_mng && !mng_info->need_fram && 
    1075810720      ((int) image->dispose == 3)) 
    10759      (void) ThrowMagickException(exception,GetMagickModule(), 
    10760        CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC", 
    10761        "`%s'",image->filename); 
     10721     png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC"); 
    1076210722 
    1076310723  /* 
     
    1076910729  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels); 
    1077010730 
    10771 #if defined(PNG_SETJMP_NOT_THREAD_SAFE) 
    10772   UnlockSemaphoreInfo(ping_semaphore); 
    10773 #endif 
    10774  
    1077510731  if (ping_have_blob != MagickFalse) 
    1077610732     (void) CloseBlob(image); 
     
    1078910745      "  exit WriteOnePNGImage()"); 
    1079010746 
     10747#ifdef PNG_SETJMP_NOT_THREAD_SAFE 
     10748  UnlockSemaphoreInfo(ping_semaphore); 
     10749#endif 
     10750 
     10751   /* }  for navigation to beginning of SETJMP-protected block. Revert to 
     10752    *    Throwing an Exception when an error occurs. 
     10753    */ 
     10754 
    1079110755  return(MagickTrue); 
    1079210756/*  End write one PNG image */ 
     10757 
    1079310758} 
    1079410759 
Note: See TracChangeset for help on using the changeset viewer.