Commit 9f586880c for imagemagick.org

commit 9f586880c2edd6c1192a6f51cbd5dadbf205984f
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sat Nov 7 12:52:11 2026 +0100

    Correct how we write the user data in the cin encoder.

diff --git a/coders/cin.c b/coders/cin.c
index 58c4bc9b2..ce6e780cb 100644
--- a/coders/cin.c
+++ b/coders/cin.c
@@ -132,8 +132,7 @@ typedef struct _CINFilmInfo

   char
     frame_id[32],
-    slate_info[200],
-    reserve[740];
+    slate_info[200];
 } CINFilmInfo;

 typedef struct _CINImageChannel
@@ -193,9 +192,6 @@ typedef struct _CINOriginationInfo
     x_pitch,
     y_pitch,
     gamma;
-
-  char
-    reserve[40];
 } CINOriginationInfo;

 typedef struct _CINUserInfo
@@ -639,8 +635,9 @@ static Image *ReadCINImage(const ImageInfo *image_info,ExceptionInfo *exception)
   offset+=4;
   if (IsFloatDefined(cin.origination.gamma) != MagickFalse)
     image->gamma=cin.origination.gamma;
-  offset+=ReadBlob(image,sizeof(cin.origination.reserve),(unsigned char *)
-    cin.origination.reserve);
+  if (DiscardBlobBytes(image,40) == MagickFalse)
+    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
+  offset+=40;
   if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
     {
       int
@@ -698,8 +695,9 @@ static Image *ReadCINImage(const ImageInfo *image_info,ExceptionInfo *exception)
       (void) CopyMagickString(property,cin.film.slate_info,
         sizeof(cin.film.slate_info));
       (void) SetImageProperty(image,"dpx:film.slate_info",property,exception);
-      offset+=ReadBlob(image,sizeof(cin.film.reserve),(unsigned char *)
-        cin.film.reserve);
+      if (DiscardBlobBytes(image,740) == MagickFalse)
+        ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
+      offset+=740;
     }
   if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
     {
@@ -976,21 +974,25 @@ static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image,
   offset=0;
   cin.file.magic=0x802A5FD7UL;
   offset+=WriteBlobLong(image,(unsigned int) cin.file.magic);
-  cin.file.image_offset=0x800;
-  offset+=WriteBlobLong(image,(unsigned int) cin.file.image_offset);
   cin.file.generic_length=0x400;
-  offset+=WriteBlobLong(image,(unsigned int) cin.file.generic_length);
   cin.file.industry_length=0x400;
-  offset+=WriteBlobLong(image,(unsigned int) cin.file.industry_length);
   cin.file.user_length=0x00;
   profile=GetImageProfile(image,"dpx:user.data");
   if (profile != (StringInfo *) NULL)
     {
+      if (GetStringInfoLength(profile) >
+          (size_t) MAGICK_UINT_MAX-0x800-0x2000+1)
+        ThrowWriterException(ResourceLimitError,"ProfileSizeExceedsLimit");
       cin.file.user_length+=(size_t) GetStringInfoLength(profile);
       cin.file.user_length=(((cin.file.user_length+0x2000-1)/0x2000)*0x2000);
     }
+  cin.file.image_offset=cin.file.generic_length+cin.file.industry_length+
+    cin.file.user_length;
+  offset+=WriteBlobLong(image,(unsigned int) cin.file.image_offset);
+  offset+=WriteBlobLong(image,(unsigned int) cin.file.generic_length);
+  offset+=WriteBlobLong(image,(unsigned int) cin.file.industry_length);
   offset+=WriteBlobLong(image,(unsigned int) cin.file.user_length);
-  cin.file.file_size=4*image->columns*image->rows+0x2000;
+  cin.file.file_size=4*image->columns*image->rows+cin.file.image_offset;
   offset+=WriteBlobLong(image,(unsigned int) cin.file.file_size);
   (void) CopyMagickString(cin.file.version,"V4.5",sizeof(cin.file.version));
   offset+=WriteBlob(image,sizeof(cin.file.version),(unsigned char *)
@@ -1144,8 +1146,7 @@ static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image,
   offset+=WriteBlobFloat(image,cin.origination.y_pitch);
   cin.origination.gamma=(float) image->gamma;
   offset+=WriteBlobFloat(image,cin.origination.gamma);
-  offset+=WriteBlob(image,sizeof(cin.origination.reserve),(unsigned char *)
-    cin.origination.reserve);
+  offset+=WriteBlobPadding(image,40,'\0');
   /*
     Image film information.
   */
@@ -1201,13 +1202,20 @@ static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image,
       sizeof(cin.film.slate_info));
   offset+=WriteBlob(image,sizeof(cin.film.slate_info),(unsigned char *)
     cin.film.slate_info);
-  offset+=WriteBlob(image,sizeof(cin.film.reserve),(unsigned char *)
-    cin.film.reserve);
+  offset+=WriteBlobPadding(image,740,'\0');
   if (profile != (StringInfo *) NULL)
-    offset+=WriteBlob(image,GetStringInfoLength(profile),
-      GetStringInfoDatum(profile));
-  while (offset < (MagickOffsetType) cin.file.image_offset)
-    offset+=WriteBlobByte(image,0x00);
+    {
+      length=GetStringInfoLength(profile);
+      count=WriteBlob(image,length,GetStringInfoDatum(profile));
+      if (count != (ssize_t) length)
+        ThrowWriterException(BlobError,"UnableToWriteBlob");
+      offset+=count;
+    }
+  length=(size_t) ((MagickOffsetType) cin.file.image_offset-offset);
+  count=WriteBlobPadding(image,length,'\0');
+  if (count != (ssize_t) length)
+    ThrowWriterException(BlobError,"UnableToWriteBlob");
+  offset+=count;
   /*
     Convert pixel packets to CIN raster image.
   */
@@ -1227,8 +1235,11 @@ static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image,
     (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
       quantum_type,pixels,exception);
     count=WriteBlob(image,length,pixels);
-    if (count != (ssize_t) length)
-      break;
+    if (count != (ssize_t)length)
+      {
+        status=MagickFalse;
+        break;
+      }
     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
       image->rows);
     if (status == MagickFalse)