File ImageMagick-CVE-2025-62594.patch of Package ImageMagick.41460

Index: ImageMagick-7.1.1-21/MagickCore/enhance.c
===================================================================
--- ImageMagick-7.1.1-21.orig/MagickCore/enhance.c
+++ ImageMagick-7.1.1-21/MagickCore/enhance.c
@@ -69,6 +69,7 @@
 #include "MagickCore/option.h"
 #include "MagickCore/pixel.h"
 #include "MagickCore/pixel-accessor.h"
+#include "MagickCore/pixel-private.h"
 #include "MagickCore/property.h"
 #include "MagickCore/quantum.h"
 #include "MagickCore/quantum-private.h"
@@ -318,11 +319,8 @@ static void ClipCLAHEHistogram(const dou
     return;
   cumulative_excess=0;
   for (i=0; i < (ssize_t) number_bins; i++)
-  {
-    excess=(ssize_t) histogram[i]-(ssize_t) clip_limit;
-    if (excess > 0)
-      cumulative_excess+=excess;
-  }
+    if (histogram[i] > clip_limit)
+      cumulative_excess+=(ssize_t) (histogram[i]-clip_limit);
   /*
     Clip histogram and redistribute excess pixels across all bins.
   */
@@ -481,9 +479,6 @@ static MagickBooleanType CLAHE(const Rec
   MemoryInfo
     *tile_cache;
 
-  unsigned short
-    *p;
-
   size_t
     limit,
     *tiles;
@@ -492,15 +487,16 @@ static MagickBooleanType CLAHE(const Rec
     y;
 
   unsigned short
-    *lut;
+    *lut,
+    *p;
 
   /*
     Contrast limited adapted histogram equalization.
   */
   if (clip_limit == 1.0)
     return(MagickTrue);
-  tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,
-    (size_t) clahe_info->y*sizeof(*tiles));
+  tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,(size_t)
+    clahe_info->y*sizeof(*tiles));
   if (tile_cache == (MemoryInfo *) NULL)
     return(MagickFalse);
   lut=(unsigned short *) AcquireQuantumMemory(NumberCLAHEGrays,sizeof(*lut));
@@ -510,7 +506,8 @@ static MagickBooleanType CLAHE(const Rec
       return(MagickFalse);
     }
   tiles=(size_t *) GetVirtualMemoryBlob(tile_cache);
-  limit=(size_t) (clip_limit*(tile_info->width*tile_info->height)/number_bins);
+  limit=(size_t) (clip_limit*((double) tile_info->width*tile_info->height)/
+    number_bins);
   if (limit < 1UL)
     limit=1UL;
   /*
@@ -535,7 +532,7 @@ static MagickBooleanType CLAHE(const Rec
         tile_info->height,histogram);
       p+=tile_info->width;
     }
-    p+=clahe_info->width*(tile_info->height-1);
+    p+=CastDoubleToPtrdiffT((double) clahe_info->width*(tile_info->height-1));
   }
   /*
     Interpolate greylevel mappings to get CLAHE image.
@@ -576,6 +573,12 @@ static MagickBooleanType CLAHE(const Rec
         }
     for (x=0; x <= (ssize_t) clahe_info->x; x++)
     {
+      double
+        Q11,
+        Q12,
+        Q21,
+        Q22;
+
       tile.width=tile_info->width;
       tile.x=x-1;
       offset.x=tile.x+1;
@@ -598,15 +601,16 @@ static MagickBooleanType CLAHE(const Rec
             tile.x=clahe_info->x-1;
             offset.x=tile.x;
           }
-      InterpolateCLAHE(clahe_info,
-        tiles+((ssize_t) number_bins*(tile.y*clahe_info->x+tile.x)),   /* Q12 */
-        tiles+((ssize_t) number_bins*(tile.y*clahe_info->x+offset.x)), /* Q22 */
-        tiles+((ssize_t) number_bins*(offset.y*clahe_info->x+tile.x)), /* Q11 */
-        tiles+((ssize_t) number_bins*(offset.y*clahe_info->x+offset.x)), /* Q21 */
-        &tile,lut,p);
+      Q12=(double) number_bins*(tile.y*clahe_info->x+tile.x);
+      Q22=(double) number_bins*(tile.y*clahe_info->x+offset.x);
+      Q11=(double) number_bins*(offset.y*clahe_info->x+tile.x);
+      Q21=(double) number_bins*(offset.y*clahe_info->x+offset.x);
+      InterpolateCLAHE(clahe_info,tiles+CastDoubleToPtrdiffT(Q12),
+        tiles+CastDoubleToPtrdiffT(Q22),tiles+CastDoubleToPtrdiffT(Q11),
+        tiles+CastDoubleToPtrdiffT(Q21),&tile,lut,p);
       p+=tile.width;
     }
-    p+=clahe_info->width*(tile.height-1);
+    p+=CastDoubleToPtrdiffT((double) clahe_info->width*(tile.height-1));
   }
   lut=(unsigned short *) RelinquishMagickMemory(lut);
   tile_cache=RelinquishVirtualMemory(tile_cache);
@@ -659,10 +663,10 @@ MagickExport MagickBooleanType CLAHEImag
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   range_info.min=0;
   range_info.max=NumberCLAHEGrays-1;
-  tile_info.width=width;
+  tile_info.width=MagickMax(width,2);
   if (tile_info.width == 0)
     tile_info.width=image->columns >> 3;
-  tile_info.height=height;
+  tile_info.height=MagickMax(height,2);
   if (tile_info.height == 0)
     tile_info.height=image->rows >> 3;
   tile_info.x=0;
Index: ImageMagick-7.1.1-21/MagickCore/image-private.h
===================================================================
--- ImageMagick-7.1.1-21.orig/MagickCore/image-private.h
+++ ImageMagick-7.1.1-21/MagickCore/image-private.h
@@ -46,13 +46,17 @@ extern "C" {
 #define MagickPHI    1.61803398874989484820458683436563811772030917980576
 #define MagickPI2    1.57079632679489661923132169163975144209858469968755
 #define MagickPI     3.1415926535897932384626433832795028841971693993751058209749445923078164062
+#define MAGICK_PTRDIFF_MAX  (PTRDIFF_MAX)
+#define MAGICK_PTRDIFF_MIN  (-PTRDIFF_MAX-1)
 #define MagickSQ1_2  0.70710678118654752440084436210484903928483593768847
 #define MagickSQ2    1.41421356237309504880168872420969807856967187537695
 #define MagickSQ2PI  2.50662827463100024161235523934010416269302368164062
 #define MAGICK_SIZE_MAX  (SIZE_MAX)
 #define MAGICK_SSIZE_MAX  (SSIZE_MAX)
 #define MAGICK_SSIZE_MIN  (-SSIZE_MAX-1)
+#define MAGICK_UINT_MAX  (UINT_MAX)
 #define MAGICK_ULONG_MAX  (ULONG_MAX)
+#define MAGICK_USHORT_MAX  (USHRT_MAX)
 #define MatteColor  "#bdbdbd"  /* gray */
 #define MatteColorRGBA  ScaleShortToQuantum(0xbdbd),\
   ScaleShortToQuantum(0xbdbd),ScaleShortToQuantum(0xbdbd),OpaqueAlpha
@@ -85,6 +89,30 @@ static inline ssize_t CastDoubleToLong(c
   return((ssize_t) x);
 }
 
+static inline ptrdiff_t CastDoubleToPtrdiffT(const double x)
+{
+  double
+    value;
+
+  if (IsNaN(x) != 0)
+    {
+      errno=ERANGE;
+      return(0);
+    }
+  value=(x < 0.0) ? ceil(x) : floor(x);
+  if (value < ((double) MAGICK_PTRDIFF_MIN))
+    {
+      errno=ERANGE;
+      return(MAGICK_PTRDIFF_MIN);
+    }
+  if (value > ((double) MAGICK_PTRDIFF_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_PTRDIFF_MAX);
+    }
+  return((ptrdiff_t) value);
+}
+
 static inline QuantumAny CastDoubleToQuantumAny(const double x)
 {
   if (IsNaN(x) != 0)
@@ -125,6 +153,102 @@ static inline size_t CastDoubleToUnsigne
   return((size_t) x);
 }
 
+static inline size_t CastDoubleToSizeT(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_SIZE_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_SIZE_MAX);
+    }
+  return((size_t) value);
+}
+
+static inline ssize_t CastDoubleToSsizeT(const double x)
+{
+  double
+    value;
+
+  if (IsNaN(x) != 0)
+    {
+      errno=ERANGE;
+      return(0);
+    }
+  value=(x < 0.0) ? ceil(x) : floor(x);
+  if (value < ((double) MAGICK_SSIZE_MIN))
+    {
+      errno=ERANGE;
+      return(MAGICK_SSIZE_MIN);
+    }
+  if (value > ((double) MAGICK_SSIZE_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_SSIZE_MAX);
+    }
+  return((ssize_t) value);
+}
+
+static inline unsigned int CastDoubleToUInt(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_UINT_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_UINT_MAX);
+    }
+  return((unsigned int) value);
+}
+
+static inline unsigned short CastDoubleToUShort(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_USHORT_MAX))
+    {
+      errno=ERANGE;
+      return(MAGICK_USHORT_MAX);
+    }
+  return((unsigned short) value);
+}
+
 static inline double DegreesToRadians(const double degrees)
 {
   return((double) (MagickPI*degrees/180.0));
openSUSE Build Service is sponsored by