Commit df6fb5838 for imagemagick.org

commit df6fb5838e243f68fee39be99e59b3553f999af8
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Tue Mar 10 10:02:42 2026 -0400

    Add cast to unsigned char helper method to check for out of band data

diff --git a/MagickCore/image-private.h b/MagickCore/image-private.h
index 0a209426c..94c4af825 100644
--- a/MagickCore/image-private.h
+++ b/MagickCore/image-private.h
@@ -55,6 +55,7 @@ extern "C" {
 #define MAGICK_SIZE_MAX  (SIZE_MAX)
 #define MAGICK_SSIZE_MAX  (SSIZE_MAX)
 #define MAGICK_SSIZE_MIN  (-SSIZE_MAX-1)
+#define MAGICK_UCHAR_MAX  (UCHAR_MAX)
 #define MAGICK_UINT_MAX  (UINT_MAX)
 #define MAGICK_ULONG_MAX  (ULONG_MAX)
 #define MAGICK_USHORT_MAX  (USHRT_MAX)
@@ -190,6 +191,30 @@ static inline ssize_t CastDoubleToSsizeT(const double x)
   return((ssize_t) value);
 }

+static inline unsigned char CastDoubleToUChar(const double x)
+{
+  double
+    value;
+
+  if (IsNaN(x) != 0)
+    {
+      errno=ERANGE;
+      return(0);
+    }
+  value=(x < 0.0) ? ceil(x) : floor(x);
+  if (value < 0.0)
+    {
+      errno=ERANGE;
+      return(0);
+    }
+  if (value >= ((double) MAGICK_UCHAR_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_UCHAR_MAX);
+    }
+  return((unsigned short) value);
+}
+
 static inline unsigned int CastDoubleToUInt(const double x)
 {
   double
diff --git a/coders/vips.c b/coders/vips.c
index b319d0cba..d54bca1cb 100644
--- a/coders/vips.c
+++ b/coders/vips.c
@@ -238,10 +238,10 @@ static inline Quantum ReadVIPSPixelNONE(Image *image,
             c=(unsigned char) ReadBlobLong(image);
             break;
           case VIPSBandFormatFLOAT:
-            c=(unsigned char) ReadBlobFloat(image);
+            c=CastDoubleToUChar((double) ReadBlobFloat(image));
             break;
           case VIPSBandFormatDOUBLE:
-            c=(unsigned char) ReadBlobDouble(image);
+            c=CastDoubleToUChar(ReadBlobDouble(image));
             break;
           default:
             c=0;
@@ -266,10 +266,10 @@ static inline Quantum ReadVIPSPixelNONE(Image *image,
             s=(unsigned short) ReadBlobLong(image);
             break;
           case VIPSBandFormatFLOAT:
-            s=(unsigned short) ReadBlobFloat(image);
+            s=CastDoubleToUShort((double) ReadBlobFloat(image));
             break;
           case VIPSBandFormatDOUBLE:
-            s=(unsigned short) ReadBlobDouble(image);
+            s=CastDoubleToUShort(ReadBlobDouble(image));
             break;
           default:
             s=0;