GraphicsMagick: Add support for a per-file write limit

GraphicsMagick Commits <[email protected]> Sun, 12 Nov 2023 15:56:13 -0600
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.1736.1699826189.7794.graphicsmagick-commit@lists.sourceforge.net>
changeset 10fedfdfe860 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=10fedfdfe860
summary: Add support for a per-file write limit

diffstat:

 ChangeLog                              |   11 +
 Magick++/lib/Magick++/Include.h        |    1 +
 VisualMagick/installer/inc/version.isx |    4 +-
 coders/art.c                           |    2 +-
 coders/avs.c                           |    4 +-
 coders/bmp.c                           |    4 +-
 coders/braille.c                       |    4 +-
 coders/cals.c                          |    7 +-
 coders/cineon.c                        |    2 +-
 coders/cmyk.c                          |    6 +-
 coders/dib.c                           |    4 +-
 coders/dpx.c                           |    2 +-
 coders/ept.c                           |    4 +-
 coders/fax.c                           |    2 +-
 coders/fits.c                          |    8 +-
 coders/gif.c                           |    4 +-
 coders/gray.c                          |    4 +-
 coders/html.c                          |    4 +-
 coders/info.c                          |    2 +-
 coders/jbig.c                          |    4 +-
 coders/jp2.c                           |    5 +-
 coders/jpeg.c                          |   13 +-
 coders/jxl.c                           |    4 +-
 coders/locale.c                        |    4 +-
 coders/logo.c                          |    4 +-
 coders/map.c                           |    2 +-
 coders/mat.c                           |    2 +-
 coders/meta.c                          |   22 +-
 coders/miff.c                          |    9 +-
 coders/mono.c                          |    4 +-
 coders/mpc.c                           |    2 +-
 coders/msl.c                           |    2 +-
 coders/mtv.c                           |    4 +-
 coders/mvg.c                           |    4 +-
 coders/otb.c                           |    4 +-
 coders/palm.c                          |    4 +-
 coders/pcd.c                           |    2 +-
 coders/pcl.c                           |    4 +-
 coders/pcx.c                           |    4 +-
 coders/pdb.c                           |    4 +-
 coders/pdf.c                           |    4 +-
 coders/pict.c                          |    4 +-
 coders/png.c                           |   70 ++--
 coders/pnm.c                           |    4 +-
 coders/ps.c                            |    4 +-
 coders/ps2.c                           |    4 +-
 coders/ps3.c                           |    4 +-
 coders/psd.c                           |    4 +-
 coders/rgb.c                           |   18 +-
 coders/sgi.c                           |    4 +-
 coders/sun.c                           |    4 +-
 coders/svg.c                           |    2 +-
 coders/tga.c                           |    4 +-
 coders/tiff.c                          |   16 +-
 coders/topol.c                         |    4 +-
 coders/txt.c                           |    4 +-
 coders/uil.c                           |    4 +-
 coders/uyvy.c                          |    4 +-
 coders/vicar.c                         |    4 +-
 coders/viff.c                          |    4 +-
 coders/wbmp.c                          |    4 +-
 coders/webp.c                          |    5 +-
 coders/wpg.c                           |    2 +-
 coders/xbm.c                           |    4 +-
 coders/xpm.c                           |    8 +-
 doc/options.imdoc                      |   38 +-
 locale/C.mgk                           |    3 +
 magick/blob.c                          |  123 ++++++--
 magick/command.c                       |   16 +-
 magick/enum_strings.c                  |    2 +
 magick/gm_messages.mc                  |    6 +
 magick/locale_c.h                      |  446 ++++++++++++++++----------------
 magick/resource.c                      |   13 +-
 magick/resource.h                      |    5 +-
 magick/version.h                       |    4 +-
 utilities/gm.1                         |   48 ++-
 www/Changelog.html                     |   13 +
 www/GraphicsMagick.html                |   28 +-
 www/animate.html                       |    2 +-
 www/compare.html                       |    2 +-
 www/composite.html                     |    2 +-
 www/convert.html                       |    2 +-
 www/display.html                       |    2 +-
 www/gm.html                            |   46 ++-
 www/identify.html                      |    2 +-
 www/import.html                        |    2 +-
 www/mogrify.html                       |    2 +-
 www/montage.html                       |    2 +-
 88 files changed, 677 insertions(+), 511 deletions(-)

diffs (truncated from 2799 to 500 lines):

diff -r 2ac24308a92f -r 10fedfdfe860 ChangeLog
--- a/ChangeLog	Sat Nov 11 08:48:16 2023 -0600
+++ b/ChangeLog	Sun Nov 12 15:56:06 2023 -0600
@@ -1,3 +1,14 @@
+2023-11-12  Bob Friesenhahn  <[email protected]>
+
+	* magick/resource.c, magick/blob.c: Add support for a per-file
+	write limit.  This imposes a limit on the number of uncompressed
+	bytes written.  The behavior when the limit is hit is similar to
+	an unexpected write error, as if the disk is full.
+	* coders/: Updated the many coders to behave correctly when faced
+	with an unexpected write error.
+	* magick/blob.c: If the write limit is hit, then the truncated
+	output file is automatically removed.
+
 2023-11-11  Bob Friesenhahn  <[email protected]>
 
 	* config/delegates.mgk.in, VisualMagick/bin/delegates.mgk:
diff -r 2ac24308a92f -r 10fedfdfe860 Magick++/lib/Magick++/Include.h
--- a/Magick++/lib/Magick++/Include.h	Sat Nov 11 08:48:16 2023 -0600
+++ b/Magick++/lib/Magick++/Include.h	Sun Nov 12 15:56:06 2023 -0600
@@ -736,6 +736,7 @@
   using MagickLib::WidthResource;
   using MagickLib::HeightResource;
   using MagickLib::ReadResource;
+  using MagickLib::WriteResource;
 
   // Virtual pixel methods
   using MagickLib::VirtualPixelMethod;
diff -r 2ac24308a92f -r 10fedfdfe860 VisualMagick/installer/inc/version.isx
--- a/VisualMagick/installer/inc/version.isx	Sat Nov 11 08:48:16 2023 -0600
+++ b/VisualMagick/installer/inc/version.isx	Sun Nov 12 15:56:06 2023 -0600
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020231111"
-#define public MagickPackageReleaseDate "snapshot-20231111"
+#define public MagickPackageVersionAddendum ".020231112"
+#define public MagickPackageReleaseDate "snapshot-20231112"
diff -r 2ac24308a92f -r 10fedfdfe860 coders/art.c
--- a/coders/art.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/art.c	Sun Nov 12 15:56:06 2023 -0600
@@ -246,7 +246,7 @@
       }
   }
 
-  CloseBlob(image);
+  status &= CloseBlob(image);
   MagickFreeResourceLimitedMemory(pixels);
 
   if (logging)
diff -r 2ac24308a92f -r 10fedfdfe860 coders/avs.c
--- a/coders/avs.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/avs.c	Sun Nov 12 15:56:06 2023 -0600
@@ -425,6 +425,6 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/bmp.c
--- a/coders/bmp.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/bmp.c	Sun Nov 12 15:56:06 2023 -0600
@@ -2802,8 +2802,8 @@
   if (adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
+  status &= CloseBlob(image);
   if (logging)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
-  return(True);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/braille.c
--- a/coders/braille.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/braille.c	Sun Nov 12 15:56:06 2023 -0600
@@ -311,6 +311,6 @@
     if (iso_11548_1 == 0)
       (void) WriteBlobByte(image,'\n');
   }
-  (void) CloseBlob(image);
-  return(MagickTrue);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/cals.c
--- a/coders/cals.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/cals.c	Sun Nov 12 15:56:06 2023 -0600
@@ -334,10 +334,9 @@
       (void) LiberateTemporaryFile(filename);
       ThrowReaderException(CoderError,UnableToWriteTemporaryFile,image);
     }
+  CloseBlob(image);
   DestroyImage(image);
-  clone_info=CloneImageInfo(image_info);
-  clone_info->blob=(void *) NULL;
-  clone_info->length=0;
+  clone_info=CloneImageInfo((ImageInfo *) NULL);
   FormatString(clone_info->filename,"tiff:%.1024s",filename);
   image=ReadImage(clone_info,exception);
   (void) LiberateTemporaryFile(filename);
@@ -545,7 +544,7 @@
   /*
     Close output file and return image
   */
-  CloseBlob(image);
+  status &= CloseBlob(image);
   return status;
 }
 
diff -r 2ac24308a92f -r 10fedfdfe860 coders/cineon.c
--- a/coders/cineon.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/cineon.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1540,6 +1540,6 @@
                     (unsigned int) TellBlob(image));
     }
 
-  CloseBlob(image);
+  status &= CloseBlob(image);
   return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/cmyk.c
--- a/coders/cmyk.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/cmyk.c	Sun Nov 12 15:56:06 2023 -0600
@@ -678,7 +678,7 @@
     packet_size,
     quantum_size,
     scene,
-    status;
+    status = MagickPass;
 
   ExportPixelAreaOptions
     export_options;
@@ -974,6 +974,6 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/dib.c
--- a/coders/dib.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/dib.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1560,6 +1560,6 @@
     }
   (void) WriteBlob(image,dib_info.image_size,(char *) pixels);
   MagickFreeResourceLimitedMemory(pixels);
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/dpx.c
--- a/coders/dpx.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/dpx.c	Sun Nov 12 15:56:06 2023 -0600
@@ -4781,7 +4781,7 @@
   MagickFreeResourceLimitedMemory(map_Y);
   MagickFreeResourceLimitedMemory(samples);
   MagickFreeResourceLimitedMemory(scanline);
-  CloseBlob(image);
+  status &= CloseBlob(image);
   if (chroma_image != (Image *) NULL)
     {
       DestroyImage(chroma_image);
diff -r 2ac24308a92f -r 10fedfdfe860 coders/ept.c
--- a/coders/ept.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/ept.c	Sun Nov 12 15:56:06 2023 -0600
@@ -696,7 +696,7 @@
                                 "Failed to open \"%s\" for read",ps_filename);
         }
 
-      CloseBlob(image);
+      status &= CloseBlob(image);
     }
   else
     {
@@ -709,5 +709,5 @@
   (void) LiberateTemporaryFile(tiff_filename);
   if (status == MagickFail)
     ThrowWriterException(FileOpenError,UnableToOpenFile,image);
-  return(MagickPass);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/fax.c
--- a/coders/fax.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/fax.c	Sun Nov 12 15:56:06 2023 -0600
@@ -335,6 +335,6 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
+  status &= CloseBlob(image);
   return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/fits.c
--- a/coders/fits.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/fits.c	Sun Nov 12 15:56:06 2023 -0600
@@ -948,7 +948,7 @@
         }
     }
 
-	/* Calculate of padding */
+        /* Calculate of padding */
     y = FITS_BLOCK_SIZE - (image->columns * image->rows * packet_size) % FITS_BLOCK_SIZE;
     if(y > 0)
       {
@@ -967,10 +967,10 @@
     image = SyncNextImageInList(image);
   } while(1);
 
-	/* Rewind image list. */
+        /* Rewind image list. */
   while (image->previous != (Image *)NULL)
       image=image->previous;
 
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/gif.c
--- a/coders/gif.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/gif.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1650,6 +1650,6 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
-  return(MagickPass);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/gray.c
--- a/coders/gray.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/gray.c	Sun Nov 12 15:56:06 2023 -0600
@@ -696,6 +696,6 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/html.c
--- a/coders/html.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/html.c	Sun Nov 12 15:56:06 2023 -0600
@@ -363,7 +363,7 @@
       (void) WriteBlobString(image,"</center>\n");
       (void) WriteBlobString(image,"</body>\n");
       (void) WriteBlobString(image,"</html>\n");
-      CloseBlob(image);
+      status &= CloseBlob(image);
       /*
         Write the image as transparent GIF.
       */
@@ -441,7 +441,7 @@
             }
         }
   (void) WriteBlobString(image,"</map>\n");
-  CloseBlob(image);
+  status &= CloseBlob(image);
   (void) strlcpy(image->filename,filename,MaxTextExtent);
   return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/info.c
--- a/coders/info.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/info.c	Sun Nov 12 15:56:06 2023 -0600
@@ -213,7 +213,7 @@
       (void) LiberateTemporaryFile(temporary_filename);
     }
 
-  CloseBlob(image);
+  status &= CloseBlob(image);
 
   return status;
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/jbig.c
--- a/coders/jbig.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/jbig.c	Sun Nov 12 15:56:06 2023 -0600
@@ -512,7 +512,7 @@
   if (image_info->adjoin)
     while (image->previous != (Image *) NULL)
       image=image->previous;
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
 #endif
diff -r 2ac24308a92f -r 10fedfdfe860 coders/jp2.c
--- a/coders/jp2.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/jp2.c	Sun Nov 12 15:56:06 2023 -0600
@@ -401,12 +401,13 @@
 /* int (*close_)(jas_stream_obj_t *obj); */
 static int BlobClose(jas_stream_obj_t *obj)
 {
+  int status;
   StreamManager
     *source = (StreamManager *) obj;
 
-  CloseBlob(source->image);
+  status = CloseBlob(source->image);
   jas_free(source);
-  return (0);
+  return (status == 0 ? EOF : 0);
 }
 
 
diff -r 2ac24308a92f -r 10fedfdfe860 coders/jpeg.c
--- a/coders/jpeg.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/jpeg.c	Sun Nov 12 15:56:06 2023 -0600
@@ -178,6 +178,9 @@
   unsigned char
     buffer[65537+200];
 
+  void
+    *jpeg_pixels;
+
 } MagickClientData;
 
 typedef struct _SourceManager
@@ -218,6 +221,7 @@
           MagickFreeMemory(client_data->profiles[i].name);
           MagickFreeResourceLimitedMemory(client_data->profiles[i].info);
         }
+      MagickFreeResourceLimitedMemory(client_data->jpeg_pixels);
 
       MagickFreeMemory(client_data);
     }
@@ -2497,7 +2501,7 @@
     *attribute;
 
   JSAMPLE
-    *jpeg_pixels;
+    *jpeg_pixels = (JSAMPLE *) NULL; /* Freed by FreeMagickClientData() */
 
   JSAMPROW
     scanline[1];
@@ -3104,6 +3108,7 @@
         LiberateMagickResource(MemoryResource,huffman_memory);
       ThrowJPEGWriterException(ResourceLimitError,MemoryAllocationFailed,image);
     }
+  client_data->jpeg_pixels = jpeg_pixels;
   scanline[0]=(JSAMPROW) jpeg_pixels;
   if (jpeg_info.data_precision > 8 && jpeg_info.data_precision <= 16)
     {
@@ -3338,8 +3343,8 @@
     LiberateMagickResource(MemoryResource,huffman_memory);
   client_data=FreeMagickClientData(client_data);
   jpeg_destroy_compress(&jpeg_info);
-  MagickFreeResourceLimitedMemory(jpeg_pixels);
-  CloseBlob(image);
-  return(True);
+  /* MagickFreeResourceLimitedMemory(jpeg_pixels); */
+  status &= CloseBlob(image);
+  return(status);
 }
 #endif
diff -r 2ac24308a92f -r 10fedfdfe860 coders/jxl.c
--- a/coders/jxl.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/jxl.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1557,10 +1557,10 @@
     /* TODO Better Error-code? */
     ThrowJXLWriterException(CoderError,NoDataReturned,image);
 
-  CloseBlob(image);
+  status &= CloseBlob(image);
 
   JXLWriteCleanup();
-  return MagickPass;
+  return(status);
 }
 
 #endif /* HasJXL */
diff -r 2ac24308a92f -r 10fedfdfe860 coders/locale.c
--- a/coders/locale.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/locale.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1166,6 +1166,6 @@
   for (i=0; i <= count; i++)
     MagickFreeMemory(locale[i]);
   MagickFreeMemory(locale);
-  CloseBlob(image);
-  return(True);
+  status &= CloseBlob(image);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/logo.c
--- a/coders/logo.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/logo.c	Sun Nov 12 15:56:06 2023 -0600
@@ -5324,8 +5324,8 @@
     p++;
   }
   (void) WriteBlobString(image,"\n  };\n");
-  CloseBlob(image);
+  status &= CloseBlob(image);
   MagickFreeMemory(blob);
   DestroyImage(logo_image);
-  return(True);
+  return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/map.c
--- a/coders/map.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/map.c	Sun Nov 12 15:56:06 2023 -0600
@@ -409,6 +409,6 @@
       ThrowMAPWriterException(FileOpenError,UnableToWriteFile,image);
   }
   MagickFreeResourceLimitedMemory(pixels);
-  CloseBlob(image);
+  status &= CloseBlob(image);
   return(status);
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/mat.c
--- a/coders/mat.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/mat.c	Sun Nov 12 15:56:06 2023 -0600
@@ -1569,7 +1569,7 @@
     image=SyncNextImageInList(image);
   }
 
-  CloseBlob(image);
+  status &= CloseBlob(image);
   MagickFreeResourceLimitedMemory(pixels);
 
   if (logging)
diff -r 2ac24308a92f -r 10fedfdfe860 coders/meta.c
--- a/coders/meta.c	Sat Nov 11 08:48:16 2023 -0600
+++ b/coders/meta.c	Sun Nov 12 15:56:06 2023 -0600
@@ -2376,8 +2376,8 @@
       if (status == MagickFail)
         ThrowWriterException(FileOpenError,UnableToOpenFile,image);
       (void) WriteBlob(image,profile_length,(void *) profile);
-      CloseBlob(image);
-      return MagickPass;
+      status &= CloseBlob(image);
+      return status;
     }
   if (LocaleCompare(image_info->magick,"IPTC") == 0)
     {
@@ -2396,8 +2396,8 @@
         ThrowWriterException(CoderError,NoIPTCInfoWasFound,image);
       info=profile+iptc_offset;
       (void) WriteBlob(image,length,info);
-      CloseBlob(image);
-      return MagickPass;
+      status &= CloseBlob(image);
+      return status;
     }
   if (LocaleCompare(image_info->magick,"8BIMTEXT") == 0)
     {
@@ -2420,7 +2420,7 @@
         status = MagickFail;
       DetachBlob(buff->blob);
       DestroyImage(buff);
-      CloseBlob(image);
+      status &= CloseBlob(image);
       return status;
     }
   if (LocaleCompare(image_info->magick,"8BIMWTEXT") == 0)
@@ -2457,8 +2457,8 @@
       (void) formatIPTC(buff,image);
       DetachBlob(buff->blob);
       DestroyImage(buff);
-      CloseBlob(image);
-      return MagickPass;
+      status &= CloseBlob(image);
+      return status;
     }
   if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0)
     {
@@ -2477,8 +2477,8 @@
       if (status == MagickFail)
         ThrowWriterException(FileOpenError,UnableToOpenFile,image);
       (void) WriteBlob(image,(int) profile_length, (char *) profile);
-      CloseBlob(image);
-      return MagickPass;
+      status &= CloseBlob(image);
+      return status;
     }
   if ((LocaleCompare(image_info->magick,"ICC") == 0) ||
       (LocaleCompare(image_info->magick,"ICM") == 0))
@@ -2493,8 +2493,8 @@
       if (status == MagickFail)
         ThrowWriterException(FileOpenError,UnableToOpenFile,image);
       (void) WriteBlob(image,profile_length,(void *) profile);
-      CloseBlob(image);
-      return MagickPass;
+      status &= CloseBlob(image);
+      return status;
     }
   return MagickFail;
 }
diff -r 2ac24308a92f -r 10fedfdfe860 coders/miff.c
--- a/coders/miff.c	Sat Nov 11 08:48:16 2023 -0600