File ImageMagick-CVE-2025-62594.patch of Package ImageMagick.41462
Index: ImageMagick-7.1.0-9/MagickCore/enhance.c
===================================================================
--- ImageMagick-7.1.0-9.orig/MagickCore/enhance.c
+++ ImageMagick-7.1.0-9/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/quantum.h"
#include "MagickCore/quantum-private.h"
#include "MagickCore/resample.h"
@@ -320,11 +321,8 @@ static void ClipCLAHEHistogram(const dou
*/
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.
*/
@@ -483,9 +481,6 @@ static MagickBooleanType CLAHE(const Rec
MemoryInfo
*tile_cache;
- unsigned short
- *p;
-
size_t
limit,
*tiles;
@@ -494,14 +489,15 @@ static MagickBooleanType CLAHE(const Rec
y;
unsigned short
- *lut;
+ *lut,
+ *p;
/*
Constrast limited adapted histogram equalization.
*/
if (clip_limit == 1.0)
return(MagickTrue);
- tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,
+ tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,(size_t)
clahe_info->y*sizeof(*tiles));
if (tile_cache == (MemoryInfo *) NULL)
return(MagickFalse);
@@ -512,7 +508,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;
/*
@@ -537,7 +534,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.
@@ -578,6 +575,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;
@@ -600,15 +603,15 @@ static MagickBooleanType CLAHE(const Rec
tile.x=clahe_info->x-1;
offset.x=tile.x;
}
- InterpolateCLAHE(clahe_info,
- tiles+(number_bins*(tile.y*clahe_info->x+tile.x)), /* Q12 */
- tiles+(number_bins*(tile.y*clahe_info->x+offset.x)), /* Q22 */
- tiles+(number_bins*(offset.y*clahe_info->x+tile.x)), /* Q11 */
- tiles+(number_bins*(offset.y*clahe_info->x+offset.x)), /* Q21 */
- &tile,lut,p);
+ 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);
@@ -661,10 +664,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.0-9/MagickCore/image-private.h
===================================================================
--- ImageMagick-7.1.0-9.orig/MagickCore/image-private.h
+++ ImageMagick-7.1.0-9/MagickCore/image-private.h
@@ -38,13 +38,17 @@ extern "C" {
#define MagickPHI 1.61803398874989484820458683436563811772030917980576
#define MagickPI2 1.57079632679489661923132169163975144209858469968755
#define MagickPI 3.14159265358979323846264338327950288419716939937510
+#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 MatteColor "#bdbdbd" /* gray */
#define PSDensityGeometry "72.0x72.0"
+#define MAGICK_UINT_MAX (UINT_MAX)
#define PSPageGeometry "612x792"
+#define MAGICK_USHORT_MAX (USHRT_MAX)
#define SaveImagesTag "Save/Images"
#define SaveImageTag "Save/Image"
#define TransparentColor "#00000000" /* transparent black */
@@ -62,6 +66,30 @@ static inline ssize_t CastDoubleToLong(c
return((ssize_t) value);
}
+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 size_t CastDoubleToUnsigned(const double x)
{
if (IsNaN(x) != 0)
@@ -82,6 +110,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));