Commit ae2ed8c81 for imagemagick.org

commit ae2ed8c81d8fad1f186e7f2bc0837b46a1c7be61
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Mon Aug 17 20:17:17 2026 -0400

    https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-3j4w-pvxj-fpjc

diff --git a/coders/mat.c b/coders/mat.c
index cf04efa04..b1eb1bed0 100644
--- a/coders/mat.c
+++ b/coders/mat.c
@@ -484,7 +484,8 @@ static void RelinquishZIPMemory(voidpf context,voidpf memory)

 #if defined(MAGICKCORE_ZLIB_DELEGATE)
 /** This procedure decompreses an image block for a new MATLAB format. */
-static Image *decompress_block(Image *orig, unsigned int *Size, ImageInfo *clone_info, ExceptionInfo *exception)
+static Image *decompress_block(Image *orig,unsigned int *Size,
+  ImageInfo *clone_info,ExceptionInfo *exception)
 {

 Image *image2;
@@ -498,26 +499,32 @@ int file;
 MagickBooleanType status;
 int zip_status;
 ssize_t total_size = 0;
+size_t compressed_total = 0;
+static const size_t MAX_ABSOLUTE_SIZE = 512UL * 1024UL * 1024UL; /* 512 MB */
+static const size_t MAX_EXPANSION_RATIO = 64; /* 64x expansion allowed */

-  if(clone_info==NULL) return NULL;
-  if(clone_info->file)    /* Close file opened from previous transaction. */
-  {
-    fclose(clone_info->file);
-    clone_info->file = NULL;
-    (void) remove_utf8(clone_info->filename);
-  }
-
-  cache_block = AcquireQuantumMemory((size_t)(*Size < MagickMinBufferExtent) ? *Size: MagickMinBufferExtent,sizeof(unsigned char *));
-  if(cache_block==NULL) return NULL;
-  decompress_block = AcquireQuantumMemory((size_t)(4096),sizeof(unsigned char *));
-  if(decompress_block==NULL)
-  {
-    RelinquishMagickMemory(cache_block);
+  if (clone_info == NULL)
     return NULL;
-  }
+  if (clone_info->file)    /* Close file opened from previous transaction. */
+    {
+      fclose(clone_info->file);
+      clone_info->file = NULL;
+      (void) remove_utf8(clone_info->filename);
+    }

+  cache_block=AcquireQuantumMemory((size_t) (*Size < MagickMinBufferExtent) ?
+    *Size: MagickMinBufferExtent,sizeof(unsigned char *));
+  if (cache_block == NULL)
+    return NULL;
+  decompress_block=AcquireQuantumMemory((size_t) (4096),
+    sizeof(unsigned char *));
+  if (decompress_block == NULL)
+    {
+      RelinquishMagickMemory(cache_block);
+      return NULL;
+    }
   mat_file=0;
-  file = AcquireUniqueFileResource(clone_info->filename);
+  file=AcquireUniqueFileResource(clone_info->filename);
   if (file != -1)
     mat_file = fdopen(file,"ab+");
   if(!mat_file)
@@ -531,8 +538,8 @@ ssize_t total_size = 0;
   (void) memset(&zip_info,0,sizeof(zip_info));
   zip_info.zalloc=AcquireZIPMemory;
   zip_info.zfree=RelinquishZIPMemory;
-  zip_info.opaque = (voidpf) NULL;
-  zip_status = inflateInit(&zip_info);
+  zip_info.opaque=(voidpf) NULL;
+  zip_status=inflateInit(&zip_info);
   if (zip_status != Z_OK)
     {
       RelinquishMagickMemory(cache_block);
@@ -541,37 +548,50 @@ ssize_t total_size = 0;
         "UnableToUncompressImage","`%s'",clone_info->filename);
       (void) fclose(mat_file);
       RelinquishUniqueFileResource(clone_info->filename);
-      return NULL;
+      return(NULL);
     }
-  /* zip_info.next_out = 8*4;*/
-
-  zip_info.avail_in = 0;
-  zip_info.total_out = 0;
-  while(*Size>0 && !EOFBlob(orig))
+  zip_info.avail_in=0;
+  zip_info.total_out=0;
+  while ((*Size > 0) && (EOFBlob(orig) == 0))
   {
-    magick_size = ReadBlob(orig, (*Size < MagickMinBufferExtent) ? *Size : MagickMinBufferExtent, (unsigned char *) cache_block);
+    magick_size=ReadBlob(orig,(*Size < MagickMinBufferExtent) ? *Size :
+      MagickMinBufferExtent,(unsigned char *) cache_block);
     if (magick_size == 0)
       break;
-    zip_info.next_in = (Bytef *) cache_block;
-    zip_info.avail_in = (uInt) magick_size;
-
-    while(zip_info.avail_in>0)
+    zip_info.next_in=(Bytef *) cache_block;
+    zip_info.avail_in=(uInt) magick_size;
+    compressed_total+=magick_size;
+    while (zip_info.avail_in > 0)
     {
-      zip_info.avail_out = 4096;
-      zip_info.next_out = (Bytef *) decompress_block;
-      zip_status = inflate(&zip_info,Z_NO_FLUSH);
+      size_t chunk_size = 0;
+      zip_info.avail_out=4096;
+      zip_info.next_out=(Bytef *) decompress_block;
+      zip_status=inflate(&zip_info,Z_NO_FLUSH);
       if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
         break;
-      extent=fwrite(decompress_block,1,4096-zip_info.avail_out,mat_file);
-      (void) extent;
-      total_size += 4096-zip_info.avail_out;
-
-      if(zip_status == Z_STREAM_END) goto DblBreak;
+      chunk_size=4096-zip_info.avail_out;
+      extent=fwrite(decompress_block,1,chunk_size,mat_file);
+      if (extent != chunk_size)
+        {
+          zip_status=Z_DATA_ERROR;
+          break;
+        }
+      total_size+=chunk_size;
+      if (compressed_total > 0)
+        {
+          if ((total_size > (ssize_t) MAX_ABSOLUTE_SIZE) ||
+              (total_size > (ssize_t) (compressed_total*MAX_EXPANSION_RATIO)))
+            {
+              zip_status=Z_DATA_ERROR;
+              break;
+            }
+        }
+      if (zip_status == Z_STREAM_END)
+        goto DblBreak;
     }
     if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
       break;
-
-    *Size -= (unsigned int) magick_size;
+    *Size-=(unsigned int) magick_size;
   }
 DblBreak:

@@ -597,8 +617,7 @@ EraseFile:
     RelinquishUniqueFileResource(clone_info->filename);
     return NULL;
   }
-
-  return image2;
+  return(image2);
 }
 #endif