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));