Version in base suite: 7.1.1.43+dfsg1-1+deb13u8 Version in overlay suite: 7.1.1.43+dfsg1-1+deb13u10 Base version: imagemagick_7.1.1.43+dfsg1-1+deb13u10 Target version: imagemagick_7.1.1.43+dfsg1-1+deb13u11 Base file: /srv/ftp-master.debian.org/ftp/pool/main/i/imagemagick/imagemagick_7.1.1.43+dfsg1-1+deb13u10.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/i/imagemagick/imagemagick_7.1.1.43+dfsg1-1+deb13u11.dsc changelog | 69 + patches/CVE-2026-53466.patch | 26 patches/CVE-2026-53467.patch | 39 + patches/CVE-2026-55595.patch | 55 + patches/CVE-2026-55597.patch | 28 patches/CVE-2026-55628-pre1.patch | 38 + patches/CVE-2026-55628-pre2.patch | 57 + patches/CVE-2026-55628-pre3.patch | 27 patches/CVE-2026-55628-pre4.patch | 35 + patches/CVE-2026-55628.patch | 87 ++ patches/CVE-2026-56361.patch | 32 patches/CVE-2026-56363.patch | 58 + patches/CVE-2026-56364_1.patch | 68 + patches/CVE-2026-56364_2.patch | 26 patches/CVE-2026-56365.patch | 27 patches/CVE-2026-56367.patch | 42 + patches/CVE-2026-56368.patch | 265 +++++++ patches/CVE-2026-56370.patch | 54 + patches/CVE-2026-56371.patch | 34 patches/CVE-2026-56376.patch | 39 + patches/CVE-2026-56377.patch | 59 + patches/CVE-2026-56378.patch | 28 patches/CVE-2026-56378_pre1.patch | 73 ++ patches/draw-7.1.2-26-post1.patch | 24 patches/draw-7.1.2-26.patch | 1315 ++++++++++++++++++++++++++++++++++++++ patches/series | 24 26 files changed, 2629 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpe7z5wyvq/imagemagick_7.1.1.43+dfsg1-1+deb13u10.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpe7z5wyvq/imagemagick_7.1.1.43+dfsg1-1+deb13u11.dsc: no acceptable signature found diff -Nru imagemagick-7.1.1.43+dfsg1/debian/changelog imagemagick-7.1.1.43+dfsg1/debian/changelog --- imagemagick-7.1.1.43+dfsg1/debian/changelog 2026-06-20 11:35:39.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/changelog 2026-07-02 20:08:14.000000000 +0000 @@ -1,3 +1,72 @@ +imagemagick (8:7.1.1.43+dfsg1-1+deb13u11) trixie-security; urgency=medium + + * Fix CVE-2026-53466: + An integer overflow in the XCF decoder can result in an out of bounds + read when a crafted image is read, potentially resulting in a crash. + * Fix CVE-2026-53467: + The MNG decoder contains a possible heap information disclosure + vulnerability because part of the pixels are left unchanged. + * Backport MagickCore/draw.c from 7.1.2-26 + * Fix CVE-2026-55577: + A heap buffer overflow occurs in the MVG decoder that could result + in an out of bounds write when processing a crafted image. + * Fix CVE-2026-55594: + A missing depth check in the MVG decoder will result in a stack overflow + when a crafted image is provided. + * Fix CVE-2026-55597: + An incorrect handling of arguments can cause a heap buffer over-write + in the JP2 encoder + * Fix CVE-2026-55628: + The `-concatenate` operation is missing policy checks, potentially resulting + in both reading and writing to paths disallowed by the security policy. + * Fix CVE-2026-56361: + Attackers can trigger heap buffer overflow by providing incorrect + morphology parameters causing single pixel memory access violations. + * Fix CVE-2026-56363: + An attacker can supply a large binomial kernel value causing integer overflow, + resulting in division by zero and application crash. + * Fix CVE-2026-56364: + A memory leak vulnerability in LoadOpenCLDeviceBenchmark() function + when parsing malformed OpenCL device profile XML files with unclosed device + elements. Attackers with write access to the OpenCL cache directory can place + malicious XML files to exhaust memory and cause denial of service. + * Fix CVE-2026-56365: + A memory leak vulnerability in the PNG encoder when writing MNG images. + * Fix CVE-2026-56367: + An integer overflow in the PSB (PSD v2) RLE decoding path + (ReadPSDChannelRLE in coders/psd.c) that causes a heap out-of-bounds read + on 32-bit builds. + * Fix CVE-2026-56368: + A memory leak vulnerability in multiple coders that write raw pixel data + where allocated objects are not properly freed. Attackers can trigger + this leak by processing specially crafted images, causing memory exhaustion + and denial of service. + * Fix CVE-2026-56370: + ImageMagick contains an out-of-bounds access vulnerability in + ConnectedComponentsImage() when processing connected-components artifacts + with invalid indices. Attackers can trigger access violations by + specifying malformed connected-components definitions via CLI, + causing denial of service or potential code execution. + * Fix CVE-2026-56371; + A memory leak in coders/txt.c when processing TXT files with texture + attributes: the texture object allocated via ReadImage is not released + when GetTypeMetrics fails, leaking memory each time a crafted TXT file + with a texture attribute is processed. + * Fix CVE-2026-56376: + A heap use-after-free in the meta coder: when memory allocation fails, + a single byte is written to a stale pointer. Remote attackers can trigger + it by processing specially crafted image files, causing a denial of service. + * Fix CVE-2026-56377: + ImageMagick contains an incorrect policy check that allows attackers + to create or truncate files disallowed by security policies. + * Fix CVE-2026-56378: + ImageMagick contains a heap out-of-bounds read in the PCD coder's DecodeImage + loop. A crafted PCD file can trigger a one-byte heap out-of-bounds read + during image decoding, resulting in denial of service and potential + disclosure of an adjacent heap byte. + + -- Bastien Roucariès Thu, 02 Jul 2026 22:08:14 +0200 + imagemagick (8:7.1.1.43+dfsg1-1+deb13u10) trixie-security; urgency=high * Fix CVE-2026-48724: diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53466.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53466.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53466.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53466.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,26 @@ +From: Cristy +Date: Fri, 5 Jun 2026 11:21:28 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pjxj-pchx-4c3m + +(cherry picked from commit 47ca7210515f3c9ea033b86fe4323a70caa74468) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pjxj-pchx-4c3m +origin: https://github.com/ImageMagick/ImageMagick/commit/47ca7210515f3c9ea033b86fe4323a70caa74468 +--- + coders/xcf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/coders/xcf.c b/coders/xcf.c +index 4c655b5..030f504 100644 +--- a/coders/xcf.c ++++ b/coders/xcf.c +@@ -753,7 +753,7 @@ static MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo, + /* if the offset is 0 then we need to read in the maximum possible + allowing for negative compression */ + if (offset2 == 0) +- offset2=(MagickOffsetType) (offset + TILE_WIDTH * TILE_WIDTH * 4* 1.5); ++ offset2=(MagickOffsetType) (offset+TILE_WIDTH*TILE_WIDTH*(3*4)/2); + /* seek to the tile offset */ + if ((offset > offset2) || (SeekBlob(image, offset, SEEK_SET) != offset)) + ThrowBinaryException(CorruptImageError,"InsufficientImageDataInFile", diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53467.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53467.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53467.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-53467.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,39 @@ +From: Cristy +Date: Sun, 7 Jun 2026 22:05:34 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8g53-9m3c-69xg#advisory-comment-224693 + +The MNG decoder contains a possible heap information disclosure vulnerability because part of the pixels are left unchanged. + +(cherry picked from commit 9d1764c43a15b78e18a7f66649989d59079a9e15) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8g53-9m3c-69xg +origin: https://github.com/ImageMagick/ImageMagick/commit/9d1764c43a15b78e18a7f66649989d59079a9e15 +--- + coders/png.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/coders/png.c b/coders/png.c +index ea3fc8d..546f0fb 100644 +--- a/coders/png.c ++++ b/coders/png.c +@@ -6576,7 +6576,7 @@ static Image *ReadOneMNGImage(MngReadInfo* mng_info, + } + + n=GetAuthenticPixels(image,0,0,image->columns,1,exception); +- (void) memcpy(next,n,length); ++ (void) memcpy(next,n,length*sizeof(*next)); + + for (y=0; y < (ssize_t) image->rows; y++) + { +@@ -6602,8 +6602,8 @@ static Image *ReadOneMNGImage(MngReadInfo* mng_info, + if (y < (ssize_t) image->rows-1) + { + n=GetAuthenticPixels(image,0,y+1,image->columns,1, +- exception); +- (void) memcpy(next,n,length); ++ exception); ++ (void) memcpy(next,n,length*sizeof(*next)); + } + + for (i=0; i < m; i++, yy++) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55595.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55595.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55595.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55595.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,55 @@ +From: Cristy +Date: Sat, 13 Jun 2026 19:33:04 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-qhmf-7fc4-8q3h + +when providing invalid arguments to the connected-components option an infinite loop will occur. + +(cherry picked from commit 549fdf2195bbac1c93e736c04f416d4d9a5d05a8) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-qhmf-7fc4-8q3h +origin: https://github.com/ImageMagick/ImageMagick/commit/549fdf2195bbac1c93e736c04f416d4d9a5d05a8 +--- + MagickCore/vision.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/MagickCore/vision.c b/MagickCore/vision.c +index ab12ed5..966128d 100644 +--- a/MagickCore/vision.c ++++ b/MagickCore/vision.c +@@ -797,7 +797,8 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + *object; + + char +- *c; ++ *c, ++ *d; + + const char + *artifact, +@@ -1177,7 +1178,11 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + { + while ((isspace((int) ((unsigned char) *c)) != 0) || (*c == ',')) + c++; +- first=(ssize_t) strtol(c,&c,10); ++ d=c; ++ first=(ssize_t) strtol(c,&d,10); ++ if (d == c) ++ break; ++ c=d; + if (first < 0) + first+=(ssize_t) component_image->colors; + last=first; +@@ -1271,7 +1276,11 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + */ + while ((isspace((int) ((unsigned char) *c)) != 0) || (*c == ',')) + c++; +- first=(ssize_t) strtol(c,&c,10); ++ d=c; ++ first=(ssize_t) strtol(c,&d,10); ++ if (d == c) ++ break; ++ c=d; + if (first < 0) + first+=(ssize_t) component_image->colors; + last=first; diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55597.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55597.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55597.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55597.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,28 @@ +From: Cristy +Date: Sat, 13 Jun 2026 19:47:19 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-c4v7-w88g-m6c4 + +(cherry picked from commit 277541927c2de8317d4167ee16d57375f24971d3) + +an incorrect handling of arguments can cause a heap buffer over-write in the JP2 encoder. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-c4v7-w88g-m6c4 +origin: https://github.com/ImageMagick/ImageMagick/commit/277541927c2de8317d4167ee16d57375f24971d3 +--- + coders/jp2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/coders/jp2.c b/coders/jp2.c +index c103bed..f873d1e 100644 +--- a/coders/jp2.c ++++ b/coders/jp2.c +@@ -1161,7 +1161,7 @@ static MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image, + jp2_image->x1=(unsigned int) (2*parameters->image_offset_x0+ + ((ssize_t) image->columns-1)*parameters->subsampling_dx+1); + jp2_image->y1=(unsigned int) (2*parameters->image_offset_y0+ +- ((ssize_t) image->rows-1)*parameters->subsampling_dx+1); ++ ((ssize_t) image->rows-1)*parameters->subsampling_dy+1); + if ((image->depth == 12) && + ((image->columns == 2048) || (image->rows == 1080) || + (image->columns == 4096) || (image->rows == 2160))) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre1.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre1.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre1.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,38 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 18:28:36 +0200 +Subject: Backport function is_symlink_utf8 + +origin: https://github.com/ImageMagick/ImageMagick/blob/7.1.2-26/MagickCore/utility-private.h#L85C1-L102C1 +--- + MagickCore/utility-private.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h +index e67295e..ab6bf6e 100644 +--- a/MagickCore/utility-private.h ++++ b/MagickCore/utility-private.h +@@ -181,6 +181,24 @@ static inline FILE *fopen_utf8(const char *path,const char *mode) + #endif + } + ++static inline MagickBooleanType is_symlink_utf8(const char *path) ++{ ++#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) ++#if defined(MAGICKCORE_POSIX_SUPPORT) ++ struct stat ++ status; ++ ++ if (lstat(path,&status) == -1) ++ return(MagickFalse); ++ return(S_ISLNK(status.st_mode) != 0 ? MagickTrue : MagickFalse); ++#else ++ return(MagickFalse); ++#endif ++#else ++ return(NTIsSymlinkWide(path)); ++#endif ++} ++ + static inline void getcwd_utf8(char *path,size_t extent) + { + #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre2.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre2.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre2.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre2.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,57 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 18:33:37 +0200 +Subject: Backport IsPathAuthorized + +Drop previous patch definition + +origin: https://github.com/ImageMagick/ImageMagick/blob/7.1.2-26/MagickCore/policy-private.h#L44C1-L52C1 +--- + MagickCore/blob.c | 4 ---- + MagickCore/policy-private.h | 12 ++++++++++++ + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/MagickCore/blob.c b/MagickCore/blob.c +index de7cef7..2dd6ee7 100644 +--- a/MagickCore/blob.c ++++ b/MagickCore/blob.c +@@ -82,10 +82,6 @@ + /* + Define declarations. + */ +-#define IsPathAuthorized(rights,filename) \ +- ((IsRightsAuthorized(PathPolicyDomain,rights,filename) != MagickFalse) && \ +- ((IsRightsAuthorizedByName(SystemPolicyDomain,"symlink",rights,"follow") != MagickFalse) || \ +- (is_symlink_utf8(filename) == MagickFalse))) + #define MagickMaxBlobExtent (8*8192) + #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) + # define MAP_ANONYMOUS MAP_ANON +diff --git a/MagickCore/policy-private.h b/MagickCore/policy-private.h +index 37916eb..27e1dc4 100644 +--- a/MagickCore/policy-private.h ++++ b/MagickCore/policy-private.h +@@ -22,6 +22,8 @@ + extern "C" { + #endif + ++#include "MagickCore/utility-private.h" ++ + #if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT + /* + Zero configuration security policy. Discussion @ +@@ -41,6 +43,16 @@ extern MagickPrivate MagickBooleanType + extern MagickPrivate void + PolicyComponentTerminus(void); + ++static inline MagickBooleanType IsPathAuthorized(const PolicyRights rights, ++ const char *filename) ++{ ++ MagickBooleanType status = ++ ((IsRightsAuthorized(PathPolicyDomain,rights,filename) != MagickFalse) && ++ ((IsRightsAuthorizedByName(SystemPolicyDomain,"symlink",rights,"follow") != MagickFalse) || ++ (is_symlink_utf8(filename) == MagickFalse))) ? MagickTrue : MagickFalse; ++ return(status); ++} ++ + #if defined(__cplusplus) || defined(c_plusplus) + } + #endif diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre3.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre3.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre3.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre3.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,27 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 18:39:57 +0200 +Subject: Backport ThrowPolicyException(tag,status) + +origin: https://github.com/ImageMagick/ImageMagick/blob/c74cd62cb55a7290f0d7f75bf723456b9260be25/MagickCore/exception-private.h#L69-L75 +--- + MagickCore/exception-private.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/MagickCore/exception-private.h b/MagickCore/exception-private.h +index e89a23b..db3c0c7 100644 +--- a/MagickCore/exception-private.h ++++ b/MagickCore/exception-private.h +@@ -66,6 +66,13 @@ extern "C" { + "`%s'",image->filename); \ + return((Image *) NULL); \ + } ++#define ThrowPolicyException(tag,status) \ ++{ \ ++ errno=EPERM; \ ++ (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, \ ++ "NotAuthorized","`%s'",tag); \ ++ return(status); \ ++} + #define ThrowReaderException(severity,tag) \ + { \ + (void) ThrowMagickException(exception,GetMagickModule(),severity,tag, \ diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre4.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre4.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre4.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628-pre4.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,35 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 20:53:03 +0200 +Subject: Export a policy symbol + +--- + MagickCore/policy.c | 2 +- + MagickCore/policy.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/MagickCore/policy.c b/MagickCore/policy.c +index cd13ae5..5855579 100644 +--- a/MagickCore/policy.c ++++ b/MagickCore/policy.c +@@ -643,7 +643,7 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception) + % + */ + +-MagickPrivate MagickBooleanType IsRightsAuthorizedByName( ++MagickExport MagickBooleanType IsRightsAuthorizedByName( + const PolicyDomain domain,const char *name,const PolicyRights rights, + const char *pattern) + { +diff --git a/MagickCore/policy.h b/MagickCore/policy.h +index fb0578d..8e5efc1 100644 +--- a/MagickCore/policy.h ++++ b/MagickCore/policy.h +@@ -60,6 +60,8 @@ extern MagickExport const PolicyInfo + + extern MagickExport MagickBooleanType + IsRightsAuthorized(const PolicyDomain,const PolicyRights,const char *), ++ IsRightsAuthorizedByName(const PolicyDomain,const char *,const PolicyRights, ++ const char *), + ListPolicyInfo(FILE *,ExceptionInfo *), + SetMagickSecurityPolicy(const char *,ExceptionInfo *), + SetMagickSecurityPolicyValue(const PolicyDomain,const char *,const char *, diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-55628.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,87 @@ +From: Cristy +Date: Sun, 14 Jun 2026 08:55:56 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-82mp-vp5c-9pf7 + +(cherry picked from commit dcba7ee9ffb0c5a22a458bf0c613bc818fcb4cc6) + +the `-concatenate` operation is missing policy checks, potentially resulting in both reading and writing to paths disallowed by the security policy + +[backport] +- use #define for MagickPathAuthorised + +bug; https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-82mp-vp5c-9pf7 +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/dcba7ee9ffb0c5a22a458bf0c613bc818fcb4cc6 +--- + MagickWand/deprecate.c | 5 +++++ + MagickWand/magick-cli.c | 6 ++++++ + 2 files changed, 11 insertions(+) + +diff --git a/MagickWand/deprecate.c b/MagickWand/deprecate.c +index ee7c678..5a48330 100644 +--- a/MagickWand/deprecate.c ++++ b/MagickWand/deprecate.c +@@ -47,6 +47,7 @@ + #include "MagickWand/wand.h" + #include "MagickCore/exception-private.h" + #include "MagickCore/monitor-private.h" ++#include "MagickCore/policy-private.h" + #include "MagickCore/string-private.h" + #include "MagickCore/thread-private.h" + #include "MagickCore/utility-private.h" +@@ -106,6 +107,8 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv, + /* + Open output file. + */ ++ if (IsPathAuthorized(WritePolicyRights,argv[argc-1]) == MagickFalse) ++ ThrowPolicyException(argv[argc-1],MagickFalse); + output=fopen_utf8(argv[argc-1],"wb"); + if (output == (FILE *) NULL) + { +@@ -116,6 +119,8 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv, + status=MagickTrue; + for (i=2; i < (ssize_t) (argc-1); i++) + { ++ if (IsPathAuthorized(ReadPolicyRights,argv[i]) == MagickFalse) ++ ThrowPolicyException(argv[i],MagickFalse); + input=fopen_utf8(argv[i],"rb"); + if (input == (FILE *) NULL) + { +diff --git a/MagickWand/magick-cli.c b/MagickWand/magick-cli.c +index 9df713e..41053f7 100644 +--- a/MagickWand/magick-cli.c ++++ b/MagickWand/magick-cli.c +@@ -54,6 +54,7 @@ + #include "MagickWand/operation.h" + #include "MagickWand/magick-cli.h" + #include "MagickWand/script-token.h" ++#include "MagickCore/policy-private.h" + #include "MagickCore/string-private.h" + #include "MagickCore/thread-private.h" + #include "MagickCore/utility-private.h" +@@ -66,6 +67,7 @@ + 5 - image counts (after option runs) + */ + #define MagickCommandDebug 0 ++ + + /* + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@@ -1255,6 +1257,8 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv, + if (ExpandFilenames(&argc,&argv) == MagickFalse) + ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed", + GetExceptionMessage(errno)); ++ if (IsPathAuthorized(WritePolicyRights,argv[argc-1]) == MagickFalse) ++ ThrowPolicyException(argv[argc-1],MagickFalse); + output=fopen_utf8(argv[argc-1],"wb"); + if (output == (FILE *) NULL) + { +@@ -1265,6 +1269,8 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv, + status=MagickTrue; + for (i=2; i < (ssize_t) (argc-1); i++) + { ++ if (IsPathAuthorized(ReadPolicyRights,argv[i]) == MagickFalse) ++ ThrowPolicyException(argv[i],MagickFalse); + input=fopen_utf8(argv[i],"rb"); + if (input == (FILE *) NULL) + { diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56361.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56361.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56361.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56361.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,32 @@ +From: Cristy +Date: Wed, 25 Mar 2026 05:52:54 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-q8h3-jv9v-57qx + +Attackers can trigger heap buffer overflow by providing incorrect morphology parameters causing single pixel memory access violations. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-q8h3-jv9v-57qx +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/a6bfb1bb7b4017ec52f5a957641d83ce29b63286 +--- + MagickCore/morphology.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/MagickCore/morphology.c b/MagickCore/morphology.c +index a7bfc7a..b8e3485 100644 +--- a/MagickCore/morphology.c ++++ b/MagickCore/morphology.c +@@ -1583,10 +1583,10 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type, + /* NOTE: user defaults set in "AcquireKernelInfo()" */ + if ( args->rho < 1.0 || args->sigma < 1.0 ) + return(DestroyKernelInfo(kernel)); /* invalid args given */ +- kernel->width = (size_t)args->rho; +- kernel->height = (size_t)args->sigma; +- if ( args->xi < 0.0 || args->xi > (double)kernel->width || +- args->psi < 0.0 || args->psi > (double)kernel->height ) ++ kernel->width = CastDoubleToSizeT(args->rho); ++ kernel->height = CastDoubleToSizeT(args->sigma); ++ if ((args->xi < 0.0) || (args->xi >= (double) kernel->width) || ++ (args->psi < 0.0) || (args->psi >= (double) kernel->height)) + return(DestroyKernelInfo(kernel)); /* invalid args given */ + kernel->x = (ssize_t) args->xi; + kernel->y = (ssize_t) args->psi; diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56363.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56363.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56363.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56363.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,58 @@ +From: Dirk Lemstra +Date: Sun, 3 May 2026 14:08:40 +0200 +Subject: Set a limit to the kernel order to avoid an overflow resulting in a + divide by zero (GHSA-vf33-6r7x-66xx) + +(cherry picked from commit d67eef71764cfeca07b4edf8a8ae922180f5f2e4) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-vf33-6r7x-66xx +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/d67eef71764cfeca07b4edf8a8ae922180f5f2e4 +--- + MagickCore/morphology.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/MagickCore/morphology.c b/MagickCore/morphology.c +index b8e3485..f4799a6 100644 +--- a/MagickCore/morphology.c ++++ b/MagickCore/morphology.c +@@ -92,19 +92,12 @@ + #define Maximize(assign,value) assign=MagickMax(assign,value) + + /* Integer Factorial Function - for a Binomial kernel */ +-#if 1 + static inline size_t fact(size_t n) + { + size_t f,l; + for(f=1, l=2; l <= n; f=f*l, l++); + return(f); + } +-#elif 1 /* glibc floating point alternatives */ +-#define fact(n) ((size_t)tgamma((double)n+1)) +-#else +-#define fact(n) ((size_t)lgamma((double)n+1)) +-#endif +- + + /* Currently these are only internal to this module */ + static void +@@ -1304,6 +1297,9 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type, + } + case BinomialKernel: + { ++ const size_t ++ max_order = (sizeof(size_t) > 4) ? 20 : 12; ++ + size_t + order_f; + +@@ -1313,6 +1309,10 @@ MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type, + kernel->width = kernel->height = ((size_t)args->rho)*2+1; + kernel->x = kernel->y = (ssize_t) (kernel->width-1)/2; + ++ /* Check if kernel order (width-1) would overflow fact() */ ++ if ((kernel->width-1) > max_order) ++ return(DestroyKernelInfo(kernel)); ++ + order_f = fact(kernel->width-1); + + kernel->values=(MagickRealType *) MagickAssumeAligned( diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_1.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_1.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_1.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,68 @@ +From: Dirk Lemstra +Date: Mon, 12 Jan 2026 18:21:15 +0100 +Subject: Fixed memory leak that happens when someone creates a corrupt + ImagemagickOpenCLDeviceProfile.xml file (GHSA-qp59-x883-77qv) + +(cherry picked from commit 951f6b0940224afc469f6a72503d6e011c688d02) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-qp59-x883-77qv +origin: https://github.com/ImageMagick/ImageMagick/commit/951f6b0940224afc469f6a72503d6e011c688d02 +--- + MagickCore/opencl.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +diff --git a/MagickCore/opencl.c b/MagickCore/opencl.c +index e9742f3..7815df0 100644 +--- a/MagickCore/opencl.c ++++ b/MagickCore/opencl.c +@@ -750,6 +750,21 @@ MagickPrivate cl_kernel AcquireOpenCLKernel(MagickCLDevice device, + */ + + #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT ++static MagickCLDeviceBenchmark* RelinquishDeviceBenchmark( ++ MagickCLDeviceBenchmark *device_benchmark) ++{ ++ device_benchmark->platform_name=(char *) RelinquishMagickMemory( ++ device_benchmark->platform_name); ++ device_benchmark->vendor_name=(char *) RelinquishMagickMemory( ++ device_benchmark->vendor_name); ++ device_benchmark->name=(char *) RelinquishMagickMemory( ++ device_benchmark->name); ++ device_benchmark->version=(char *) RelinquishMagickMemory( ++ device_benchmark->version); ++ return((MagickCLDeviceBenchmark *) RelinquishMagickMemory( ++ device_benchmark)); ++} ++ + static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml) + { + char +@@ -835,17 +850,7 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml) + } + } + } +- +- device_benchmark->platform_name=(char *) RelinquishMagickMemory( +- device_benchmark->platform_name); +- device_benchmark->vendor_name=(char *) RelinquishMagickMemory( +- device_benchmark->vendor_name); +- device_benchmark->name=(char *) RelinquishMagickMemory( +- device_benchmark->name); +- device_benchmark->version=(char *) RelinquishMagickMemory( +- device_benchmark->version); +- device_benchmark=(MagickCLDeviceBenchmark *) RelinquishMagickMemory( +- device_benchmark); ++ device_benchmark=RelinquishDeviceBenchmark(device_benchmark); + continue; + } + (void) GetNextToken(q,(const char **) NULL,extent,token); +@@ -905,8 +910,7 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml) + } + } + token=(char *) RelinquishMagickMemory(token); +- device_benchmark=(MagickCLDeviceBenchmark *) RelinquishMagickMemory( +- device_benchmark); ++ device_benchmark=RelinquishDeviceBenchmark(device_benchmark); + } + + static MagickBooleanType CanWriteProfileToFile(const char *filename) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_2.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_2.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_2.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56364_2.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,26 @@ +From: Dirk Lemstra +Date: Sat, 24 Jan 2026 22:23:07 +0100 +Subject: Allow null value when calling RelinquishDeviceBenchmark. + +(cherry picked from commit 5fd4e5ad05a986b00e1519fa308ca3c5cf3d09d8) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-qp59-x883-77qv +origin: https://github.com/ImageMagick/ImageMagick/commit/5fd4e5ad05a986b00e1519fa308ca3c5cf3d09d8 +--- + MagickCore/opencl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/MagickCore/opencl.c b/MagickCore/opencl.c +index 7815df0..797afd1 100644 +--- a/MagickCore/opencl.c ++++ b/MagickCore/opencl.c +@@ -753,6 +753,9 @@ MagickPrivate cl_kernel AcquireOpenCLKernel(MagickCLDevice device, + static MagickCLDeviceBenchmark* RelinquishDeviceBenchmark( + MagickCLDeviceBenchmark *device_benchmark) + { ++ if (device_benchmark == (MagickCLDeviceBenchmark*) NULL) ++ return((MagickCLDeviceBenchmark *) NULL); ++ + device_benchmark->platform_name=(char *) RelinquishMagickMemory( + device_benchmark->platform_name); + device_benchmark->vendor_name=(char *) RelinquishMagickMemory( diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56365.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56365.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56365.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56365.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,27 @@ +From: Cristy +Date: Thu, 9 Apr 2026 10:18:13 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-x928-4434-crqj + +A memory leak vulnerability in the PNG encoder when writing MNG images. Attackers can trigger the encoder failure condition to exhaust memory resources and cause denial of service. + +(cherry picked from commit ca761f220bbf0470e2e7967639bcfb5be305ad28) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-x928-4434-crqj +origin: https://github.com/ImageMagick/ImageMagick/commit/ca761f220bbf0470e2e7967639bcfb5be305ad28 +--- + coders/png.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/coders/png.c b/coders/png.c +index 546f0fb..66078da 100644 +--- a/coders/png.c ++++ b/coders/png.c +@@ -13656,6 +13656,7 @@ static MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image, + if (status == MagickFalse) + { + (void) CloseBlob(image); ++ mng_info=(MngWriteInfo *) RelinquishMagickMemory(mng_info); + return(MagickFalse); + } + (void) CatchImageException(image); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56367.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56367.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56367.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56367.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,42 @@ +From: Cristy +Date: Sat, 24 Jan 2026 09:26:05 -0500 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-273h-m46v-96q4 + +An integer overflow in the PSB (PSD v2) RLE decoding path (ReadPSDChannelRLE in coders/psd.c) that causes a heap out-of-bounds read on 32-bit builds. Processing a crafted PSB file can lead to information disclosure or a crash. + +(cherry picked from commit 5b91ab69af614024255fd93dcc9a62b41fbc435c) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-273h-m46v-96q4 +origin: https://github.com/ImageMagick/ImageMagick/commit/5b91ab69af614024255fd93dcc9a62b41fbc435c7 +--- + coders/psd.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/coders/psd.c b/coders/psd.c +index 404bd5f..61803b0 100644 +--- a/coders/psd.c ++++ b/coders/psd.c +@@ -1331,7 +1331,6 @@ static MagickBooleanType ReadPSDChannelZip(Image *image, + ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", + image->filename); + } +- memset(pixels,0,count*sizeof(*pixels)); + if (ReadBlob(image,compact_size,compact_pixels) != (ssize_t) compact_size) + { + pixels=(unsigned char *) RelinquishMagickMemory(pixels); +@@ -2329,7 +2328,13 @@ static MagickBooleanType ReadPSDMergedImage(const ImageInfo *image_info, + sizes=(MagickOffsetType *) NULL; + if (compression == RLE) + { +- sizes=ReadPSDRLESizes(image,psd_info,image->rows*psd_info->channels); ++ size_t ++ extent; ++ ++ if (HeapOverflowSanityCheckGetSize(image->rows,psd_info->channels,&extent) != MagickFalse) ++ ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", ++ image->filename); ++ sizes=ReadPSDRLESizes(image,psd_info,extent); + if (sizes == (MagickOffsetType *) NULL) + ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", + image->filename); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56368.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56368.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56368.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56368.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,265 @@ +From: Dirk Lemstra +Date: Sat, 7 Feb 2026 09:31:08 +0100 +Subject: Fixed possible memory leak in multiple coders that write raw pixel + data (GHSA-wfx3-6g53-9fgc) + +(cherry picked from commit fe0a49a58ac5b7a18ff2618b6207dcad71123e43) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-wfx3-6g53-9fgc +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/fe0a49a58ac5b7a18ff2618b6207dcad71123e43 +--- + coders/bgr.c | 20 ++++++++++++++++---- + coders/cmyk.c | 25 ++++++++++++++++++++----- + coders/gray.c | 10 ++++++++-- + coders/rgb.c | 20 ++++++++++++++++---- + coders/ycbcr.c | 20 ++++++++++++++++---- + 5 files changed, 76 insertions(+), 19 deletions(-) + +diff --git a/coders/bgr.c b/coders/bgr.c +index d35aef5..98a2ed7 100644 +--- a/coders/bgr.c ++++ b/coders/bgr.c +@@ -1344,7 +1344,10 @@ static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1371,7 +1374,10 @@ static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1398,7 +1404,10 @@ static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1428,7 +1437,10 @@ static MagickBooleanType WriteBGRImage(const ImageInfo *image_info,Image *image, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +diff --git a/coders/cmyk.c b/coders/cmyk.c +index e469ea3..6c7b0f6 100644 +--- a/coders/cmyk.c ++++ b/coders/cmyk.c +@@ -1471,7 +1471,10 @@ static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1498,7 +1501,10 @@ static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1525,7 +1531,10 @@ static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1552,7 +1561,10 @@ static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1581,7 +1593,10 @@ static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +diff --git a/coders/gray.c b/coders/gray.c +index c1b4ee0..3809104 100644 +--- a/coders/gray.c ++++ b/coders/gray.c +@@ -1002,7 +1002,10 @@ static MagickBooleanType WriteGRAYImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1032,7 +1035,10 @@ static MagickBooleanType WriteGRAYImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +diff --git a/coders/rgb.c b/coders/rgb.c +index aa26c96..3ad12c8 100644 +--- a/coders/rgb.c ++++ b/coders/rgb.c +@@ -1586,7 +1586,10 @@ static MagickBooleanType WriteRGBImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1613,7 +1616,10 @@ static MagickBooleanType WriteRGBImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1640,7 +1646,10 @@ static MagickBooleanType WriteRGBImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +@@ -1669,7 +1678,10 @@ static MagickBooleanType WriteRGBImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + const Quantum +diff --git a/coders/ycbcr.c b/coders/ycbcr.c +index 05f2151..8d9026f 100644 +--- a/coders/ycbcr.c ++++ b/coders/ycbcr.c +@@ -1291,7 +1291,10 @@ static MagickBooleanType WriteYCBCRImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + p=GetVirtualPixels(image,0,y,image->columns,1,exception); +@@ -1315,7 +1318,10 @@ static MagickBooleanType WriteYCBCRImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + p=GetVirtualPixels(image,0,y,image->columns,1,exception); +@@ -1339,7 +1345,10 @@ static MagickBooleanType WriteYCBCRImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + p=GetVirtualPixels(image,0,y,image->columns,1,exception); +@@ -1365,7 +1374,10 @@ static MagickBooleanType WriteYCBCRImage(const ImageInfo *image_info, + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) +- return(status); ++ { ++ quantum_info=DestroyQuantumInfo(quantum_info); ++ return(status); ++ } + for (y=0; y < (ssize_t) image->rows; y++) + { + p=GetVirtualPixels(image,0,y,image->columns,1,exception); diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56370.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56370.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56370.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56370.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,54 @@ +From: Cristy +Date: Wed, 1 Apr 2026 09:21:04 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pmpg-6pww-fg6q + +(cherry picked from commit 2ab24d74865ab92faeeefe0fec890abf1e88e57c) + +an out-of-bounds access vulnerability in ConnectedComponentsImage() when processing connected-components artifacts with invalid indices. Attackers can trigger access violations by specifying malformed connected-components definitions via CLI, causing denial of service or potential code execution. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pmpg-6pww-fg6q +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/2ab24d74865ab92faeeefe0fec890abf1e88e57c +--- + MagickCore/vision.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/MagickCore/vision.c b/MagickCore/vision.c +index 966128d..bcb08ae 100644 +--- a/MagickCore/vision.c ++++ b/MagickCore/vision.c +@@ -1196,7 +1196,9 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + } + step=(ssize_t) (first > last ? -1 : 1); + for ( ; first != (last+step); first+=step) +- object[first].merge=MagickFalse; ++ if ((first >= 0) && ++ (first < (ssize_t) component_image->colors)) ++ object[first].merge=MagickFalse; + } + } + artifact=GetImageArtifact(image,"connected-components:keep-top"); +@@ -1228,7 +1230,11 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + qsort((void *) top_objects,component_image->colors,sizeof(*top_objects), + CCObjectInfoCompare); + for (i=top_ids+1; i < (ssize_t) component_image->colors; i++) +- object[top_objects[i].id].merge=MagickTrue; ++ { ++ ssize_t id = (ssize_t) top_objects[i].id; ++ if ((id >= 0) && (id < (ssize_t) component_image->colors)) ++ object[id].merge=MagickTrue; ++ } + top_objects=(CCObjectInfo *) RelinquishMagickMemory(top_objects); + } + artifact=GetImageArtifact(image,"connected-components:remove-colors"); +@@ -1294,7 +1300,9 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, + } + step=(ssize_t) (first > last ? -1 : 1); + for ( ; first != (last+step); first+=step) +- object[first].merge=MagickTrue; ++ if ((first >= 0) && ++ (first < (ssize_t) component_image->colors)) ++ object[first].merge=MagickTrue; + } + artifact=GetImageArtifact(image,"connected-components:perimeter-threshold"); + if (artifact != (const char *) NULL) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56371.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56371.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56371.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56371.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,34 @@ +From: Dirk Lemstra +Date: Fri, 6 Feb 2026 22:37:42 +0100 +Subject: Fixed possible memory leak (GHSA-3q5f-gmjc-38r8) + +(cherry picked from commit e6394098af39a9689bb5f0b4eb6a9968e449a8d3) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-3q5f-gmjc-38r8 +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/e6394098af39a9689bb5f0b4eb6a9968e449a8d3 +--- + coders/txt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/coders/txt.c b/coders/txt.c +index 7fbd730..3f1d2ae 100644 +--- a/coders/txt.c ++++ b/coders/txt.c +@@ -271,6 +271,7 @@ static Image *ReadTEXTImage(const ImageInfo *image_info, + if (status == MagickFalse) + { + draw_info=DestroyDrawInfo(draw_info); ++ texture=DestroyImageList(texture); + ThrowReaderException(TypeError,"UnableToGetTypeMetrics"); + } + page.y=CastDoubleToLong(ceil((double) page.y+metrics.ascent-0.5)); +@@ -345,8 +346,7 @@ static Image *ReadTEXTImage(const ImageInfo *image_info, + (void) SetImageProgressMonitor(image,progress_monitor,image->client_data); + } + (void) AnnotateImage(image,draw_info,exception); +- if (texture != (Image *) NULL) +- texture=DestroyImageList(texture); ++ texture=DestroyImageList(texture); + draw_info=DestroyDrawInfo(draw_info); + if (CloseBlob(image) == MagickFalse) + status=MagickFalse; diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56376.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56376.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56376.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56376.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,39 @@ +From: Dirk Lemstra +Date: Fri, 20 Feb 2026 15:55:29 +0100 +Subject: Corrected possible use after free when allocation fails + (GHSA-2gq3-ww97-wfjm) + +(cherry picked from commit f5049954f12c6fcf090a776767526d2a4708d58b) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-2gq3-ww97-wfjm +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/f5049954f12c6fcf090a776767526d2a4708d58b +--- + coders/meta.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/coders/meta.c b/coders/meta.c +index 0fe2d96..926da70 100644 +--- a/coders/meta.c ++++ b/coders/meta.c +@@ -273,11 +273,9 @@ static char *super_fgets(char **b, size_t *blen, Image *file) + tlen=(size_t) (q-p); + len<<=1; + buffer=(unsigned char *) ResizeQuantumMemory(p,len+2UL,sizeof(*p)); ++ p=(unsigned char *) NULL; + if (buffer == (unsigned char *) NULL) +- { +- p=(unsigned char *) RelinquishMagickMemory(p); +- break; +- } ++ break; + p=buffer; + q=p+tlen; + } +@@ -600,6 +598,7 @@ static char *super_fgets_w(char **b, size_t *blen, Image *file) + tlen=(size_t) (q-p); + len<<=1; + buffer=(unsigned char *) ResizeQuantumMemory(p,len+2,sizeof(*p)); ++ p=(unsigned char *) NULL; + if (buffer == (unsigned char *) NULL) + break; + p=buffer; diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56377.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56377.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56377.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56377.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,59 @@ +From: Cristy +Date: Wed, 20 May 2026 22:26:20 -0400 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-gm48-c7f2-v67p + +ImageMagick contains an incorrect policy check that allows attackers to create or truncate files disallowed by security policies. Remote attackers can bypass path policy restrictions in sandboxed conversion services to write arbitrary files outside intended boundaries. + +(cherry picked from commit 3705205e1424d379c2fc46c026c8560ccea0509e) + +[backport] +- do not change policy.c part already backported from 7.1.2-26 +- add includes + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-gm48-c7f2-v67p +origin: backport, https://github.com/ImageMagick/ImageMagick/commit/3705205e1424d379c2fc46c026c8560ccea0509e +--- + MagickCore/blob.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/MagickCore/blob.c b/MagickCore/blob.c +index 2dd6ee7..5f1adf5 100644 +--- a/MagickCore/blob.c ++++ b/MagickCore/blob.c +@@ -78,6 +78,7 @@ + #if defined(MAGICKCORE_BZLIB_DELEGATE) + #include "bzlib.h" + #endif ++#include "MagickCore/policy-private.h" + + /* + Define declarations. +@@ -3524,6 +3525,13 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info, + } + (void) CopyMagickString(image->filename,filename,MagickPathExtent); + } ++ if (IsPathAuthorized(rights,filename) == MagickFalse) ++ { ++ errno=EPERM; ++ (void) ThrowMagickException(exception,GetMagickModule(), ++ PolicyError,"NotAuthorized","`%s'",filename); ++ return(MagickFalse); ++ } + } + if (image_info->file != (FILE *) NULL) + { +@@ -3684,13 +3692,6 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info, + (void) SetStreamBuffering(image_info,blob_info); + } + } +- if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse) +- { +- errno=EPERM; +- (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, +- "NotAuthorized","`%s'",filename); +- return(MagickFalse); +- } + blob_info->status=0; + blob_info->error_number=0; + if (blob_info->type != UndefinedStream) diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,28 @@ +From: Cristy +Date: Fri, 13 Feb 2026 19:01:42 -0500 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-wgxp-q8xq-wpp9 + +ImageMagick before 7.1.2-15 (and 6.x before 6.9.13-40) contains a heap out-of-bounds read in the PCD coder's DecodeImage loop. A crafted PCD file can trigger a one-byte heap out-of-bounds read during image decoding, resulting in denial of service and potential disclosure of an adjacent heap byte. + +(cherry picked from commit 436e5d2589e3c0adc10d9aa189e81d5d088d8207) + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-wgxp-q8xq-wpp9 +origin: https://github.com/ImageMagick/ImageMagick/commit/436e5d2589e3c0adc10d9aa189e81d5d088d8207 +--- + coders/pcd.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/coders/pcd.c b/coders/pcd.c +index 4db1288..b8d1764 100644 +--- a/coders/pcd.c ++++ b/coders/pcd.c +@@ -327,6 +327,8 @@ static MagickBooleanType DecodeImage(Image *image,unsigned char *luma, + PCDGetBits(1); + continue; + } ++ if ((q < luma) || (q >= sentinel)) ++ break; + if (r->key < 128) + quantum=(ssize_t) (*q)+r->key; + else diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378_pre1.patch imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378_pre1.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378_pre1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/CVE-2026-56378_pre1.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,73 @@ +From: Cristy +Date: Sat, 7 Feb 2026 16:08:44 -0500 +Subject: + https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-x2j6-6h5m-gjg4 + +(cherry picked from commit 13e1eac8ce533e96da10054edd3930bbcf07ce71) + +ImageMagick before 7.1.2-15 (and 6.x before 6.9.13-40) contains a heap out-of-bounds read in the PCD coder's DecodeImage loop. A crafted PCD file can trigger a one-byte heap out-of-bounds read during image decoding, resulting in denial of service and potential disclosure of an adjacent heap byte. + +bug: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-x2j6-6h5m-gjg4 +origin: https://github.com/ImageMagick/ImageMagick/commit/13e1eac8ce533e96da10054edd3930bbcf07ce71 +--- + coders/pcd.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/coders/pcd.c b/coders/pcd.c +index 279c85f..4db1288 100644 +--- a/coders/pcd.c ++++ b/coders/pcd.c +@@ -185,7 +185,8 @@ static MagickBooleanType DecodeImage(Image *image,unsigned char *luma, + quantum; + + unsigned char +- *buffer; ++ *buffer, ++ *sentinel; + + /* + Initialize Huffman tables. +@@ -264,6 +265,7 @@ static MagickBooleanType DecodeImage(Image *image,unsigned char *luma, + length=0; + plane=0; + row=0; ++ sentinel=luma+3*(image->columns+1)*image->rows; + for (q=luma; EOFBlob(image) == MagickFalse; ) + { + if (IsSync(sum) != 0) +@@ -329,6 +331,8 @@ static MagickBooleanType DecodeImage(Image *image,unsigned char *luma, + quantum=(ssize_t) (*q)+r->key; + else + quantum=(ssize_t) (*q)+r->key-256; ++ if ((q < luma) || (q >= sentinel)) ++ break; + *q=(unsigned char) ((quantum < 0) ? 0 : (quantum > 255) ? 255 : quantum); + q++; + PCDGetBits(r->length); +@@ -339,6 +343,8 @@ static MagickBooleanType DecodeImage(Image *image,unsigned char *luma, + for (i=0; i < (ssize_t) (image->columns > 1536 ? 3 : 1); i++) + pcd_table[i]=(PCDTable *) RelinquishMagickMemory(pcd_table[i]); + buffer=(unsigned char *) RelinquishMagickMemory(buffer); ++ if ((q < luma) || (q >= sentinel)) ++ ThrowBinaryException(CorruptImageError,"CorruptImage",image->filename); + return(MagickTrue); + } + +@@ -778,7 +784,7 @@ static Image *ReadPCDImage(const ImageInfo *image_info,ExceptionInfo *exception) + for (i=0; i < (4*0x800); i++) + (void) ReadBlobByte(image); + status=DecodeImage(image,luma,chroma1,chroma2,exception); +- if ((scene >= 5) && status) ++ if ((scene >= 5) && (status != MagickFalse)) + { + /* + Recover luminance deltas for 3072x2048 image. +@@ -875,6 +881,8 @@ static Image *ReadPCDImage(const ImageInfo *image_info,ExceptionInfo *exception) + if (image_info->scene != 0) + for (i=0; i < (ssize_t) image_info->scene; i++) + AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); ++ if (status == MagickFalse) ++ return(image=DestroyImageList(image)); + return(GetFirstImageInList(image)); + } + diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26-post1.patch imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26-post1.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26-post1.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26-post1.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,24 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 09:22:42 +0200 +Subject: Post backport fix for 7.1.2-26 of MagickCore/draw.c + +--- + MagickCore/draw.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/MagickCore/draw.c b/MagickCore/draw.c +index 964bced..22db50c 100644 +--- a/MagickCore/draw.c ++++ b/MagickCore/draw.c +@@ -101,6 +101,11 @@ + status=MagickFalse; \ + break; \ + } ++ ++ ++static inline float MagickSafeReciprocal(const float x) { ++ return PerceptibleReciprocal(x); ++} + + /* + Typedef declarations. diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26.patch imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26.patch --- imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26.patch 1970-01-01 00:00:00.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/draw-7.1.2-26.patch 2026-07-02 20:08:14.000000000 +0000 @@ -0,0 +1,1315 @@ +From: =?utf-8?q?Bastien_Roucari=C3=A8s?= +Date: Fri, 3 Jul 2026 09:18:36 +0200 +Subject: Update MagickCore/draw.c to 7.1.2.26 + +This will close at least CVE-2026-55577, CVE-2026-55594 + +origin: https://github.com/ImageMagick/ImageMagick/blob/7.1.2-26/MagickCore/draw.c +--- + MagickCore/draw.c | 457 +++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 300 insertions(+), 157 deletions(-) + +diff --git a/MagickCore/draw.c b/MagickCore/draw.c +index 5f4d280..964bced 100644 +--- a/MagickCore/draw.c ++++ b/MagickCore/draw.c +@@ -24,7 +24,7 @@ + % You may not use this file except in compliance with the License. You may % + % obtain a copy of the License at % + % % +-% https://imagemagick.org/script/license.php % ++% https://imagemagick.org/license/ % + % % + % Unless required by applicable law or agreed to in writing, software % + % distributed under the License is distributed on an "AS IS" BASIS, % +@@ -341,15 +341,15 @@ MagickExport DrawInfo *CloneDrawInfo(const ImageInfo *image_info, + x; + + for (x=0; fabs(draw_info->dash_pattern[x]) >= MagickEpsilon; x++) ; +- clone_info->dash_pattern=(double *) AcquireQuantumMemory((size_t) (2*x+2), ++ clone_info->dash_pattern=(double *) AcquireQuantumMemory((size_t) (x+1), + sizeof(*clone_info->dash_pattern)); + if (clone_info->dash_pattern == (double *) NULL) + ThrowFatalException(ResourceLimitFatalError, + "UnableToAllocateDashPattern"); +- (void) memset(clone_info->dash_pattern,0,(size_t) (2*x+2)* ++ (void) memset(clone_info->dash_pattern,0,(size_t) (x+1)* + sizeof(*clone_info->dash_pattern)); + (void) memcpy(clone_info->dash_pattern,draw_info->dash_pattern,(size_t) +- (x+1)*sizeof(*clone_info->dash_pattern)); ++ x*sizeof(*clone_info->dash_pattern)); + } + clone_info->gradient=draw_info->gradient; + if (draw_info->gradient.stops != (StopInfo *) NULL) +@@ -1140,7 +1140,7 @@ static AffineMatrix InverseAffineMatrix(const AffineMatrix *affine) + double + determinant; + +- determinant=PerceptibleReciprocal(affine->sx*affine->sy-affine->rx* ++ determinant=MagickSafeReciprocal(affine->sx*affine->sy-affine->rx* + affine->ry); + inverse_affine.sx=determinant*affine->sy; + inverse_affine.rx=determinant*(-affine->rx); +@@ -1238,11 +1238,11 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image, + inverse_affine=InverseAffineMatrix(affine); + if (edge.y1 < 0.0) + edge.y1=0.0; +- if (edge.y2 > (image->rows-1.0)) +- edge.y2=image->rows-1.0; ++ if (edge.y2 > ((double) image->rows-1.0)) ++ edge.y2=(double) image->rows-1.0; + GetPixelInfo(image,&zero); +- start=CastDoubleToLong(ceil(edge.y1-0.5)); +- stop=CastDoubleToLong(floor(edge.y2+0.5)); ++ start=CastDoubleToSsizeT(ceil(edge.y1-0.5)); ++ stop=CastDoubleToSsizeT(floor(edge.y2+0.5)); + source_view=AcquireVirtualCacheView(source,exception); + image_view=AcquireAuthenticCacheView(image,exception); + #if defined(MAGICKCORE_OPENMP_SUPPORT) +@@ -1274,17 +1274,17 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image, + continue; + if (inverse_edge.x1 < 0.0) + inverse_edge.x1=0.0; +- if (inverse_edge.x2 > image->columns-1.0) +- inverse_edge.x2=image->columns-1.0; +- q=GetCacheViewAuthenticPixels(image_view,CastDoubleToLong( +- ceil(inverse_edge.x1-0.5)),y,(size_t) CastDoubleToLong(floor( ++ if (inverse_edge.x2 > ((double) image->columns-1.0)) ++ inverse_edge.x2=(double) image->columns-1.0; ++ q=GetCacheViewAuthenticPixels(image_view,CastDoubleToSsizeT( ++ ceil(inverse_edge.x1-0.5)),y,(size_t) CastDoubleToSsizeT(floor( + inverse_edge.x2+0.5)-ceil(inverse_edge.x1-0.5)+1),1,exception); + if (q == (Quantum *) NULL) + continue; + pixel=zero; + composite=zero; +- for (x=CastDoubleToLong(ceil(inverse_edge.x1-0.5)); +- x <= CastDoubleToLong(floor(inverse_edge.x2+0.5)); x++) ++ for (x=CastDoubleToSsizeT(ceil(inverse_edge.x1-0.5)); ++ x <= CastDoubleToSsizeT(floor(inverse_edge.x2+0.5)); x++) + { + point.x=(double) x*inverse_affine.sx+y*inverse_affine.ry+ + inverse_affine.tx; +@@ -1798,6 +1798,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info, + clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); + clone_info->miterlimit=0; + dash_polygon[0]=primitive_info[0]; ++ dash_polygon[0].closed_subpath=MagickFalse; + scale=ExpandAffine(&draw_info->affine); + length=scale*draw_info->dash_pattern[0]; + offset=fabs(draw_info->dash_offset) >= MagickEpsilon ? +@@ -1848,10 +1849,11 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info, + if ((n & 0x01) != 0) + { + dash_polygon[0]=primitive_info[0]; ++ dash_polygon[0].closed_subpath=MagickFalse; + dash_polygon[0].point.x=(double) (primitive_info[i-1].point.x+dx* +- total_length*PerceptibleReciprocal(maximum_length)); ++ total_length*MagickSafeReciprocal(maximum_length)); + dash_polygon[0].point.y=(double) (primitive_info[i-1].point.y+dy* +- total_length*PerceptibleReciprocal(maximum_length)); ++ total_length*MagickSafeReciprocal(maximum_length)); + j=1; + } + else +@@ -1859,10 +1861,11 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info, + if ((j+1) > (ssize_t) number_vertices) + break; + dash_polygon[j]=primitive_info[i-1]; ++ dash_polygon[j].closed_subpath=MagickFalse; + dash_polygon[j].point.x=(double) (primitive_info[i-1].point.x+dx* +- total_length*PerceptibleReciprocal(maximum_length)); ++ total_length*MagickSafeReciprocal(maximum_length)); + dash_polygon[j].point.y=(double) (primitive_info[i-1].point.y+dy* +- total_length*PerceptibleReciprocal(maximum_length)); ++ total_length*MagickSafeReciprocal(maximum_length)); + dash_polygon[j].coordinates=1; + j++; + dash_polygon[0].coordinates=(size_t) j; +@@ -1889,6 +1892,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info, + ((n & 0x01) == 0) && (j > 1)) + { + dash_polygon[j]=primitive_info[i-1]; ++ dash_polygon[j].closed_subpath=MagickFalse; + dash_polygon[j].point.x+=MagickEpsilon; + dash_polygon[j].point.y+=MagickEpsilon; + dash_polygon[j].coordinates=1; +@@ -1961,7 +1965,7 @@ static inline double GetStopColorOffset(const GradientInfo *gradient, + q.y=(double) y-gradient_vector->y1; + length=sqrt(q.x*q.x+q.y*q.y); + gamma=sqrt(p.x*p.x+p.y*p.y)*length; +- gamma=PerceptibleReciprocal(gamma); ++ gamma=MagickSafeReciprocal(gamma); + scale=p.x*q.x+p.y*q.y; + offset=gamma*scale*length; + return(offset); +@@ -1979,10 +1983,10 @@ static inline double GetStopColorOffset(const GradientInfo *gradient, + } + v.x=(double) (((x-gradient->center.x)*cos(DegreesToRadians( + gradient->angle)))+((y-gradient->center.y)*sin(DegreesToRadians( +- gradient->angle))))*PerceptibleReciprocal(gradient->radii.x); ++ gradient->angle))))*MagickSafeReciprocal(gradient->radii.x); + v.y=(double) (((x-gradient->center.x)*sin(DegreesToRadians( + gradient->angle)))-((y-gradient->center.y)*cos(DegreesToRadians( +- gradient->angle))))*PerceptibleReciprocal(gradient->radii.y); ++ gradient->angle))))*MagickSafeReciprocal(gradient->radii.y); + return(sqrt(v.x*v.x+v.y*v.y)); + } + } +@@ -2095,7 +2099,7 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + composite=zero; + offset=GetStopColorOffset(gradient,0,y); + if (gradient->type != RadialGradient) +- offset*=PerceptibleReciprocal(length); ++ offset*=MagickSafeReciprocal(length); + width=(size_t) (bounding_box.x+(ssize_t) bounding_box.width); + for (x=bounding_box.x; x < (ssize_t) width; x++) + { +@@ -2105,12 +2109,12 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + case UndefinedSpread: + case PadSpread: + { +- if ((x != CastDoubleToLong(ceil(gradient_vector->x1-0.5))) || +- (y != CastDoubleToLong(ceil(gradient_vector->y1-0.5)))) ++ if ((x != CastDoubleToSsizeT(ceil(gradient_vector->x1-0.5))) || ++ (y != CastDoubleToSsizeT(ceil(gradient_vector->y1-0.5)))) + { + offset=GetStopColorOffset(gradient,x,y); + if (gradient->type != RadialGradient) +- offset*=PerceptibleReciprocal(length); ++ offset*=MagickSafeReciprocal(length); + } + for (i=0; i < (ssize_t) gradient->number_stops; i++) + if (offset < gradient->stops[i].offset) +@@ -2133,12 +2137,12 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + } + case ReflectSpread: + { +- if ((x != CastDoubleToLong(ceil(gradient_vector->x1-0.5))) || +- (y != CastDoubleToLong(ceil(gradient_vector->y1-0.5)))) ++ if ((x != CastDoubleToSsizeT(ceil(gradient_vector->x1-0.5))) || ++ (y != CastDoubleToSsizeT(ceil(gradient_vector->y1-0.5)))) + { + offset=GetStopColorOffset(gradient,x,y); + if (gradient->type != RadialGradient) +- offset*=PerceptibleReciprocal(length); ++ offset*=MagickSafeReciprocal(length); + } + if (offset < 0.0) + offset=(-offset); +@@ -2175,8 +2179,8 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + + antialias=MagickFalse; + repeat=0.0; +- if ((x != CastDoubleToLong(ceil(gradient_vector->x1-0.5))) || +- (y != CastDoubleToLong(ceil(gradient_vector->y1-0.5)))) ++ if ((x != CastDoubleToSsizeT(ceil(gradient_vector->x1-0.5))) || ++ (y != CastDoubleToSsizeT(ceil(gradient_vector->y1-0.5)))) + { + offset=GetStopColorOffset(gradient,x,y); + if (gradient->type == LinearGradient) +@@ -2188,7 +2192,7 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + repeat=fmod(offset,length); + antialias=(repeat < length) && ((repeat+1.0) > length) ? + MagickTrue : MagickFalse; +- offset=PerceptibleReciprocal(length)*repeat; ++ offset=MagickSafeReciprocal(length)*repeat; + } + else + { +@@ -2199,7 +2203,7 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + repeat=fmod(offset,gradient->radius); + antialias=repeat+1.0 > gradient->radius ? MagickTrue : + MagickFalse; +- offset=repeat*PerceptibleReciprocal(gradient->radius); ++ offset=repeat*MagickSafeReciprocal(gradient->radius); + } + } + for (i=0; i < (ssize_t) gradient->number_stops; i++) +@@ -2275,72 +2279,65 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image, + % + */ + +-static MagickBooleanType CheckPrimitiveExtent(MVGInfo *mvg_info, ++static inline MagickBooleanType CheckPrimitiveExtent(MVGInfo *mvg_info, + const double pad) + { +- char +- **text = (char **) NULL; +- + double +- extent; ++ proposed_extent; ++ ++ PrimitiveInfo ++ *primitive_info; + + size_t +- quantum; ++ extent; + + ssize_t + i; + +- /* +- Check if there is enough storage for drawing primitives. +- */ +- quantum=sizeof(**mvg_info->primitive_info); +- extent=(double) mvg_info->offset+pad+(PrimitiveExtentPad+1)*(double) quantum; +- if (extent <= (double) *mvg_info->extent) ++ if ((mvg_info == (MVGInfo *) NULL) || ++ (mvg_info->primitive_info == (PrimitiveInfo **) NULL) || ++ (*mvg_info->primitive_info == (PrimitiveInfo *) NULL) || ++ (mvg_info->extent == (size_t *) NULL)) ++ return(MagickFalse); ++ proposed_extent=mvg_info->offset+pad+PrimitiveExtentPad+1.0; ++ if ((proposed_extent <= 0.0) || (proposed_extent > (double) MAGICK_SIZE_MAX)) ++ return(MagickFalse); ++ extent=CastDoubleToSizeT(ceil(proposed_extent)); ++ if (extent <= *mvg_info->extent) + return(MagickTrue); +- if ((extent >= (double) GetMaxMemoryRequest()) || (IsNaN(extent) != 0)) ++ if (extent > (GetMaxMemoryRequest()/sizeof(PrimitiveInfo))) + return(MagickFalse); +- if (mvg_info->offset > 0) +- { +- text=(char **) AcquireQuantumMemory((size_t) mvg_info->offset, +- sizeof(*text)); +- if (text == (char **) NULL) +- return(MagickFalse); +- for (i=0; i < mvg_info->offset; i++) +- text[i]=(*mvg_info->primitive_info)[i].text; +- } +- *mvg_info->primitive_info=(PrimitiveInfo *) ResizeQuantumMemory( +- *mvg_info->primitive_info,(size_t) (extent+1),quantum); +- if (*mvg_info->primitive_info != (PrimitiveInfo *) NULL) ++ primitive_info=(PrimitiveInfo *) ResizeQuantumMemory( ++ *mvg_info->primitive_info,extent+1,sizeof(PrimitiveInfo)); ++ if (primitive_info == (PrimitiveInfo *) NULL) + { +- if (text != (char **) NULL) +- text=(char **) RelinquishMagickMemory(text); +- *mvg_info->extent=(size_t) extent; +- for (i=mvg_info->offset+1; i <= (ssize_t) extent; i++) +- { +- (*mvg_info->primitive_info)[i].primitive=UndefinedPrimitive; +- (*mvg_info->primitive_info)[i].text=(char *) NULL; +- } +- return(MagickTrue); ++ /* ++ Create a stack to unwind; report failure. ++ */ ++ extent=(size_t) PrimitiveExtentPad; ++ primitive_info=(PrimitiveInfo *) AcquireCriticalMemory(extent* ++ sizeof(*primitive_info)); ++ (void) memset(primitive_info,0,extent*sizeof(*primitive_info)); ++ *mvg_info->primitive_info=primitive_info; ++ *mvg_info->extent=extent; ++ mvg_info->offset=0; ++ ThrowMagickException(mvg_info->exception,GetMagickModule(), ++ ResourceLimitError,"MemoryAllocationFailed","`%s'",""); ++ return(MagickFalse); + } ++ primitive_info[extent].primitive=UndefinedPrimitive; ++ primitive_info[extent].text=(char *) NULL; + /* +- Reallocation failed, allocate a primitive to facilitate unwinding. ++ Commit updated buffer. + */ +- if (text != (char **) NULL) +- { +- for (i=0; i < mvg_info->offset; i++) +- if (text[i] != (char *) NULL) +- text[i]=DestroyString(text[i]); +- text=(char **) RelinquishMagickMemory(text); +- } +- (void) ThrowMagickException(mvg_info->exception,GetMagickModule(), +- ResourceLimitError,"MemoryAllocationFailed","`%s'",""); +- *mvg_info->primitive_info=(PrimitiveInfo *) AcquireCriticalMemory((size_t) +- (PrimitiveExtentPad+1)*quantum); +- (void) memset(*mvg_info->primitive_info,0,(size_t) ((PrimitiveExtentPad+1)* +- quantum)); +- *mvg_info->extent=1; +- mvg_info->offset=0; +- return(MagickFalse); ++ for (i=(ssize_t) *mvg_info->extent; i < (ssize_t) extent; i++) ++ { ++ primitive_info[i].primitive=UndefinedPrimitive; ++ primitive_info[i].text=(char *) NULL; ++ } ++ *mvg_info->primitive_info=primitive_info; ++ *mvg_info->extent=extent; ++ return(MagickTrue); + } + + static inline double GetDrawValue(const char *magick_restrict string, +@@ -2369,7 +2366,8 @@ static int MVGMacroCompare(const void *target,const void *source) + return(strcmp(p,q)); + } + +-static SplayTreeInfo *GetMVGMacros(const char *primitive) ++static SplayTreeInfo *GetMVGMacros(const char *primitive, ++ ExceptionInfo *exception) + { + char + *macro, +@@ -2438,7 +2436,14 @@ static SplayTreeInfo *GetMVGMacros(const char *primitive) + n--; + } + if (LocaleCompare(token,"push") == 0) +- n++; ++ { ++ if (n++ > MagickMaxRecursionDepth) ++ { ++ (void) ThrowMagickException(exception,GetMagickModule(), ++ DrawError,"VectorGraphicsNestedTooDeeply","`%s'",token); ++ break; ++ } ++ } + if ((n == 0) && (end >= start)) + { + size_t +@@ -2465,7 +2470,28 @@ static SplayTreeInfo *GetMVGMacros(const char *primitive) + return(macros); + } + +-static inline MagickBooleanType IsPoint(const char *point) ++static inline MagickBooleanType IsValidListChar(int c) ++{ ++ if ((c >= '0') && (c <= '9')) ++ return(MagickTrue); ++ switch (c) ++ { ++ case '.': ++ case '+': ++ case '-': ++ case ',': ++ case ' ': ++ case '\t': ++ case '\r': ++ case '\n': ++ break; ++ default: ++ return(MagickFalse); ++ } ++ return(MagickTrue); ++} ++ ++static inline MagickBooleanType IsValidPoint(const char *point) + { + char + *p; +@@ -2481,9 +2507,10 @@ static inline MagickBooleanType IsPoint(const char *point) + static inline MagickBooleanType TracePoint(PrimitiveInfo *primitive_info, + const PointInfo point) + { ++ primitive_info->point=point; + primitive_info->coordinates=1; + primitive_info->closed_subpath=MagickFalse; +- primitive_info->point=point; ++ primitive_info->text=(char *) NULL; + return(MagickTrue); + } + +@@ -2638,7 +2665,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + defsDepth=0; + symbolDepth=0; + cursor=0.0; +- macros=GetMVGMacros(primitive); ++ macros=GetMVGMacros(primitive,exception); + status=MagickTrue; + for (q=primitive; *q != '\0'; ) + { +@@ -2677,30 +2704,40 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- affine.rx=GetDrawValue(token,&next_token); ++ affine.ry=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- affine.ry=GetDrawValue(token,&next_token); ++ affine.rx=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + affine.sy=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + affine.tx=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + affine.ty=GetDrawValue(token,&next_token); +@@ -2756,10 +2793,10 @@ static MagickBooleanType RenderMVGContent(Image *image, + /* + Identify recursion. + */ +- for (i=0; i < n; i++) ++ for (i=0; i <= n; i++) + if (LocaleCompare(token,graphic_context[i]->id) == 0) + break; +- if (i < n) ++ if (i <= n) + break; + if (classDepth++ > MagickMaxRecursionDepth) + { +@@ -2781,6 +2818,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + /* + Inject class elements in stream. + */ ++ (void) CloneString(&graphic_context[n]->id,token); + offset=(ssize_t) (p-primitive); + elements=AcquireString(primitive); + elements[offset]='\0'; +@@ -3185,7 +3223,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (LocaleCompare("letter-spacing",keyword) == 0) + { + (void) GetNextToken(q,&q,extent,token); +- if (IsPoint(token) == MagickFalse) ++ if (IsValidPoint(token) == MagickFalse) + break; + clone_info=CloneDrawInfo((ImageInfo *) NULL,graphic_context[n]); + clone_info->text=AcquireString(" "); +@@ -3269,7 +3307,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (graphic_context[n]->fill.alpha != (double) TransparentAlpha) + { + graphic_context[n]->fill.alpha=graphic_context[n]->fill_alpha; +- graphic_context[n]->stroke.alpha=graphic_context[n]->stroke_alpha; ++ graphic_context[n]->stroke.alpha= ++ graphic_context[n]->stroke_alpha; + } + else + { +@@ -3430,18 +3469,24 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + segment.y1=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + segment.x2=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + segment.y2=GetDrawValue(token,&next_token); +@@ -3450,6 +3495,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (LocaleCompare(type,"radial") == 0) + { + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + } +@@ -3466,7 +3513,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + } + if ((q == (char *) NULL) || (*q == '\0') || + (p == (char *) NULL) || ((q-4) < p) || +- ((q-p+4+1) > extent)) ++ ((size_t) (q-p+4+1) > extent)) + { + status=MagickFalse; + break; +@@ -3509,6 +3556,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + (void) ThrowMagickException(exception,GetMagickModule(), + ResourceLimitError,"MemoryAllocationFailed","`%s'", + image->filename); ++ status=MagickFalse; + break; + } + graphic_context[n]=CloneDrawInfo((ImageInfo *) NULL, +@@ -3519,9 +3567,12 @@ static MagickBooleanType RenderMVGContent(Image *image, + (void) CloneString(&graphic_context[n]->id,token); + } + if (n > MagickMaxRecursionDepth) +- (void) ThrowMagickException(exception,GetMagickModule(), +- DrawError,"VectorGraphicsNestedTooDeeply","`%s'", +- image->filename); ++ { ++ (void) ThrowMagickException(exception,GetMagickModule(), ++ DrawError,"VectorGraphicsNestedTooDeeply","`%s'", ++ image->filename); ++ status=MagickFalse; ++ } + break; + } + if (LocaleCompare("mask",token) == 0) +@@ -3541,28 +3592,34 @@ static MagickBooleanType RenderMVGContent(Image *image, + (void) GetNextToken(q,&q,extent,token); + (void) CopyMagickString(name,token,MagickPathExtent); + (void) GetNextToken(q,&q,extent,token); +- region.x=CastDoubleToLong(ceil(GetDrawValue(token, ++ region.x=CastDoubleToSsizeT(ceil(GetDrawValue(token, + &next_token)-0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- region.y=CastDoubleToLong(ceil(GetDrawValue(token, ++ region.y=CastDoubleToSsizeT(ceil(GetDrawValue(token, + &next_token)-0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- region.width=CastDoubleToUnsigned(floor(GetDrawValue( +- token,&next_token)+0.5)); ++ region.width=CastDoubleToSizeT(floor(GetDrawValue(token, ++ &next_token)+0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- region.height=CastDoubleToUnsigned(GetDrawValue(token, ++ region.height=CastDoubleToSizeT(GetDrawValue(token, + &next_token)+0.5); + if (token == next_token) + ThrowPointExpectedException(token,exception); +@@ -3646,6 +3703,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + affine.sy=GetDrawValue(token,&next_token); +@@ -3688,6 +3747,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + (void) ThrowMagickException(exception,GetMagickModule(), + ResourceLimitError,"MemoryAllocationFailed","`%s'", + image->filename); ++ status=MagickFalse; + break; + } + (void) GetNextToken(q,&q,extent,token); +@@ -3743,16 +3803,18 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (graphic_context[n]->dash_pattern != (double *) NULL) + graphic_context[n]->dash_pattern=(double *) + RelinquishMagickMemory(graphic_context[n]->dash_pattern); +- if (IsPoint(q) != MagickFalse) ++ if (IsValidPoint(q) != MagickFalse) + { + const char + *r; + + r=q; + (void) GetNextToken(r,&r,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(r,&r,extent,token); +- for (x=0; IsPoint(token) != MagickFalse; x++) ++ for (x=0; IsValidPoint(token) != MagickFalse; x++) + { + (void) GetNextToken(r,&r,extent,token); + if (*token == ',') +@@ -3774,6 +3836,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + for (j=0; j < x; j++) + { + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + graphic_context[n]->dash_pattern[j]=GetDrawValue(token, +@@ -3783,7 +3847,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (graphic_context[n]->dash_pattern[j] <= 0.0) + status=MagickFalse; + } +- if ((x & 0x01) != 0) ++ if (((x & 0x01) != 0) && (j == x)) + for ( ; j < (2*x); j++) + graphic_context[n]->dash_pattern[j]= + graphic_context[n]->dash_pattern[j-x]; +@@ -3937,6 +4001,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + affine.ty=GetDrawValue(token,&next_token); +@@ -3979,29 +4045,35 @@ static MagickBooleanType RenderMVGContent(Image *image, + if (LocaleCompare("viewbox",keyword) == 0) + { + (void) GetNextToken(q,&q,extent,token); +- graphic_context[n]->viewbox.x=CastDoubleToLong(ceil( ++ graphic_context[n]->viewbox.x=CastDoubleToSsizeT(ceil( + GetDrawValue(token,&next_token)-0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- graphic_context[n]->viewbox.y=CastDoubleToLong( ++ graphic_context[n]->viewbox.y=CastDoubleToSsizeT( + ceil(GetDrawValue(token,&next_token)-0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- graphic_context[n]->viewbox.width=CastDoubleToUnsigned( +- floor(GetDrawValue(token,&next_token)+0.5)); ++ graphic_context[n]->viewbox.width=CastDoubleToSizeT(floor( ++ GetDrawValue(token,&next_token)+0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); +- graphic_context[n]->viewbox.height=(size_t) CastDoubleToUnsigned( +- floor(GetDrawValue(token,&next_token)+0.5)); ++ graphic_context[n]->viewbox.height=CastDoubleToSizeT(floor( ++ GetDrawValue(token,&next_token)+0.5)); + if (token == next_token) + ThrowPointExpectedException(token,exception); + break; +@@ -4078,6 +4150,7 @@ static MagickBooleanType RenderMVGContent(Image *image, + i=0; + mvg_info.offset=i; + j=0; ++ primitive_info[0].primitive=primitive_type; + primitive_info[0].point.x=0.0; + primitive_info[0].point.y=0.0; + primitive_info[0].coordinates=0; +@@ -4088,13 +4161,15 @@ static MagickBooleanType RenderMVGContent(Image *image, + /* + Define points. + */ +- if (IsPoint(q) == MagickFalse) ++ if (IsValidPoint(q) == MagickFalse) + break; + (void) GetNextToken(q,&q,extent,token); + point.x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(q,&q,extent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(q,&q,extent,token); + point.y=GetDrawValue(token,&next_token); +@@ -4115,6 +4190,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) CheckPrimitiveExtent(&mvg_info,(double) + number_points); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + } + if (status == MagickFalse) + break; +@@ -4212,18 +4289,21 @@ static MagickBooleanType RenderMVGContent(Image *image, + /* + Resize based on speculative points required by primitive. + */ +- number_points+=coordinates+1; ++ number_points+=(size_t) coordinates+1; + if (number_points < (size_t) coordinates) + { + (void) ThrowMagickException(exception,GetMagickModule(), + ResourceLimitError,"MemoryAllocationFailed","`%s'", + image->filename); ++ status=MagickFalse; + break; + } + mvg_info.offset=i; + status&=(MagickStatusType) CheckPrimitiveExtent(&mvg_info,(double) + number_points); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + } + status&=(MagickStatusType) CheckPrimitiveExtent(&mvg_info, + PrimitiveExtentPad); +@@ -4244,6 +4324,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TracePoint(primitive_info+j, + primitive_info[j].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4257,6 +4339,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TraceLine(primitive_info+j, + primitive_info[j].point,primitive_info[j+1].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4270,6 +4354,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TraceRectangle(primitive_info+j, + primitive_info[j].point,primitive_info[j+1].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4300,6 +4386,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + primitive_info[j].point,primitive_info[j+1].point, + primitive_info[j+2].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4313,6 +4401,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TraceArc(&mvg_info,primitive_info[j].point, + primitive_info[j+1].point,primitive_info[j+2].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4333,6 +4423,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + primitive_info[j].point,primitive_info[j+1].point, + primitive_info[j+2].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4346,6 +4438,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TraceCircle(&mvg_info, + primitive_info[j].point,primitive_info[j+1].point); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4382,6 +4476,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + status&=(MagickStatusType) TraceBezier(&mvg_info, + primitive_info[j].coordinates); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + i=j+(ssize_t) primitive_info[j].coordinates; + break; + } +@@ -4389,6 +4485,8 @@ static MagickBooleanType RenderMVGContent(Image *image, + { + coordinates=(double) TracePath(&mvg_info,token,exception); + primitive_info=(*mvg_info.primitive_info); ++ if (status == MagickFalse) ++ break; + if (coordinates < 0.0) + { + status=MagickFalse; +@@ -4901,7 +4999,7 @@ static double GetFillAlpha(PolygonInfo *polygon_info,const double mid, + /* + Point is closest to point between q & q+1. + */ +- alpha=PerceptibleReciprocal(alpha); ++ alpha=MagickSafeReciprocal(alpha); + beta=delta.x*(y-q->y)-delta.y*(x-q->x); + distance=alpha*beta*beta; + } +@@ -5092,10 +5190,10 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image, + (double) image->columns-1.0 : bounds.x2; + bounds.y2=bounds.y2 < 0.0 ? 0.0 : bounds.y2 >= (double) image->rows-1.0 ? + (double) image->rows-1.0 : bounds.y2; +- poly_extent.x1=CastDoubleToLong(ceil(bounds.x1-0.5)); +- poly_extent.y1=CastDoubleToLong(ceil(bounds.y1-0.5)); +- poly_extent.x2=CastDoubleToLong(floor(bounds.x2+0.5)); +- poly_extent.y2=CastDoubleToLong(floor(bounds.y2+0.5)); ++ poly_extent.x1=CastDoubleToSsizeT(ceil(bounds.x1-0.5)); ++ poly_extent.y1=CastDoubleToSsizeT(ceil(bounds.y1-0.5)); ++ poly_extent.x2=CastDoubleToSsizeT(floor(bounds.x2+0.5)); ++ poly_extent.y2=CastDoubleToSsizeT(floor(bounds.y2+0.5)); + number_threads=(size_t) GetMagickNumberThreads(image,image,(size_t) + (poly_extent.y2-poly_extent.y1+1),1); + status=ClonePolygonEdgesTLS(polygon_info,number_threads,exception); +@@ -5139,8 +5237,8 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image, + GetPixelInfo(image,&pixel); + for ( ; x <= poly_extent.x2; x++) + { +- if ((x == CastDoubleToLong(ceil(primitive_info->point.x-0.5))) && +- (y == CastDoubleToLong(ceil(primitive_info->point.y-0.5)))) ++ if ((x == CastDoubleToSsizeT(ceil(primitive_info->point.x-0.5))) && ++ (y == CastDoubleToSsizeT(ceil(primitive_info->point.y-0.5)))) + { + GetFillColor(draw_info,x-poly_extent.x1,y-poly_extent.y1,&pixel, + exception); +@@ -5280,8 +5378,8 @@ static void LogPrimitiveInfo(const PrimitiveInfo *primitive_info) + coordinates, + y; + +- x=CastDoubleToLong(ceil(primitive_info->point.x-0.5)); +- y=CastDoubleToLong(ceil(primitive_info->point.y-0.5)); ++ x=CastDoubleToSsizeT(ceil(primitive_info->point.x-0.5)); ++ y=CastDoubleToSsizeT(ceil(primitive_info->point.y-0.5)); + switch (primitive_info->primitive) + { + case AlphaPrimitive: +@@ -5395,8 +5493,8 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image, + status&=(MagickStatusType) SetImageMask(image,CompositePixelMask, + draw_info->composite_mask,exception); + } +- x=CastDoubleToLong(ceil(primitive_info->point.x-0.5)); +- y=CastDoubleToLong(ceil(primitive_info->point.y-0.5)); ++ x=CastDoubleToSsizeT(ceil(primitive_info->point.x-0.5)); ++ y=CastDoubleToSsizeT(ceil(primitive_info->point.y-0.5)); + image_view=AcquireAuthenticCacheView(image,exception); + switch (primitive_info->primitive) + { +@@ -5631,7 +5729,8 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image, + affine; + + char +- composite_geometry[MagickPathExtent]; ++ composite_geometry[MagickPathExtent], ++ magic[MagickPathExtent] = {'\0'}; + + Image + *composite_image, +@@ -5669,11 +5768,8 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image, + clone_info->size=DestroyString(clone_info->size); + if (clone_info->extract != (char *) NULL) + clone_info->extract=DestroyString(clone_info->extract); +- if ((LocaleCompare(clone_info->magick,"ftp") != 0) && +- (LocaleCompare(clone_info->magick,"http") != 0) && +- (LocaleCompare(clone_info->magick,"https") != 0) && +- (LocaleCompare(clone_info->magick,"mvg") != 0) && +- (LocaleCompare(clone_info->magick,"vid") != 0)) ++ GetPathComponent(clone_info->filename,MagickPath,magic); ++ if (*magic == '\0') + composite_images=ReadImage(clone_info,exception); + else + (void) ThrowMagickException(exception,GetMagickModule(), +@@ -5689,8 +5785,8 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image, + composite_images=DestroyImageList(composite_images); + (void) SetImageProgressMonitor(composite_image,(MagickProgressMonitor) + NULL,(void *) NULL); +- x1=CastDoubleToLong(ceil(primitive_info[1].point.x-0.5)); +- y1=CastDoubleToLong(ceil(primitive_info[1].point.y-0.5)); ++ x1=CastDoubleToSsizeT(ceil(primitive_info[1].point.x-0.5)); ++ y1=CastDoubleToSsizeT(ceil(primitive_info[1].point.y-0.5)); + if (((x1 != 0L) && (x1 != (ssize_t) composite_image->columns)) || + ((y1 != 0L) && (y1 != (ssize_t) composite_image->rows))) + { +@@ -5902,6 +5998,8 @@ static MagickBooleanType DrawRoundLinecap(Image *image, + ssize_t + i; + ++ if (primitive_info->coordinates < 1) ++ return(MagickFalse); + for (i=0; i < 4; i++) + linecap[i]=(*primitive_info); + linecap[0].coordinates=4; +@@ -6295,7 +6393,7 @@ static MagickBooleanType TraceArcPath(MVGInfo *mvg_info,const PointInfo start, + beta=points[1].y-points[0].y; + if (fabs(alpha*alpha+beta*beta) < MagickEpsilon) + return(TraceLine(primitive_info,start,end)); +- factor=PerceptibleReciprocal(alpha*alpha+beta*beta)-0.25; ++ factor=MagickSafeReciprocal(alpha*alpha+beta*beta)-0.25; + if (factor <= 0.0) + factor=0.0; + else +@@ -6313,7 +6411,7 @@ static MagickBooleanType TraceArcPath(MVGInfo *mvg_info,const PointInfo start, + else + if ((theta > 0.0) && (sweep == MagickFalse)) + theta-=2.0*MagickPI; +- arc_segments=(size_t) CastDoubleToLong(ceil(fabs((double) (theta/(0.5* ++ arc_segments=(size_t) CastDoubleToSsizeT(ceil(fabs((double) (theta/(0.5* + MagickPI+MagickEpsilon))))); + status=MagickTrue; + p=primitive_info; +@@ -6562,8 +6660,8 @@ static MagickBooleanType TraceEllipse(MVGInfo *mvg_info,const PointInfo center, + primitive_info->coordinates=0; + if ((fabs(radii.x) < MagickEpsilon) || (fabs(radii.y) < MagickEpsilon)) + return(MagickTrue); +- delta=PerceptibleReciprocal(MagickMax(radii.x,radii.y)); +- step=MagickPI/(MagickPI*PerceptibleReciprocal(delta))/8.0; ++ delta=MagickSafeReciprocal(MagickMax(radii.x,radii.y)); ++ step=MagickPI/(MagickPI*MagickSafeReciprocal(delta))/8.0; + angle.x=DegreesToRadians(arc.x); + y=arc.y; + while (y < arc.x) +@@ -6703,40 +6801,56 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + do + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + arc.x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + arc.y=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + angle=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + large_arc=StringToLong(token) != 0 ? MagickTrue : MagickFalse; + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + sweep=StringToLong(token) != 0 ? MagickTrue : MagickFalse; ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -6754,7 +6868,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'c': +@@ -6769,12 +6883,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + for (i=1; i < 4; i++) + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -6796,7 +6914,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'H': +@@ -6805,6 +6923,8 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + do + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); +@@ -6822,7 +6942,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'l': +@@ -6834,12 +6954,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + do + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -6858,7 +6982,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'M': +@@ -6879,12 +7003,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + do + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -6906,7 +7034,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'q': +@@ -6921,12 +7049,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + for (i=1; i < 3; i++) + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -6950,7 +7082,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 's': +@@ -6967,12 +7099,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + for (i=2; i < 4; i++) + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -7002,7 +7138,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 't': +@@ -7019,12 +7155,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + for (i=2; i < 3; i++) + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + x=GetDrawValue(token,&next_token); + if (token == next_token) + ThrowPointExpectedException(token,exception); + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -7054,7 +7194,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'v': +@@ -7066,6 +7206,8 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + do + { + (void) GetNextToken(p,&p,MagickPathExtent,token); ++ if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse) ++ ThrowPointExpectedException(token,exception); + if (*token == ',') + (void) GetNextToken(p,&p,MagickPathExtent,token); + y=GetDrawValue(token,&next_token); +@@ -7083,7 +7225,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path, + p++; + if (*p == ',') + p++; +- } while (IsPoint(p) != MagickFalse); ++ } while (IsValidPoint(p) != MagickFalse); + break; + } + case 'z': +@@ -7420,9 +7562,9 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + offset.x=primitive_info[number_vertices-1].point.x-primitive_info[0].point.x; + offset.y=primitive_info[number_vertices-1].point.y-primitive_info[0].point.y; + closed_path=(fabs(offset.x) < MagickEpsilon) && +- (fabs(offset.y) < MagickEpsilon) ? MagickTrue : MagickFalse; +- if (((draw_info->linejoin == RoundJoin) || +- (draw_info->linejoin == MiterJoin)) && (closed_path != MagickFalse)) ++ (fabs(offset.y) < MagickEpsilon) ? MagickTrue : MagickFalse; ++ if ((draw_info->linejoin == RoundJoin) || ++ ((draw_info->linejoin == MiterJoin) && (closed_path != MagickFalse))) + { + polygon_primitive[number_vertices]=primitive_info[1]; + number_vertices++; +@@ -7431,6 +7573,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + /* + Compute the slope for the first line segment, p. + */ ++ closed_path=primitive_info[0].closed_subpath; + dx.p=0.0; + dy.p=0.0; + for (n=1; n < (ssize_t) number_vertices; n++) +@@ -7495,7 +7638,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + else + { + slope.p=dy.p/dx.p; +- inverse_slope.p=(-1.0*PerceptibleReciprocal(slope.p)); ++ inverse_slope.p=(-1.0*MagickSafeReciprocal(slope.p)); + } + mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0; + miterlimit=(double) (draw_info->miterlimit*draw_info->miterlimit*mid*mid); +@@ -7562,7 +7705,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + else + { + slope.q=dy.q/dx.q; +- inverse_slope.q=(-1.0*PerceptibleReciprocal(slope.q)); ++ inverse_slope.q=(-1.0*MagickSafeReciprocal(slope.q)); + } + offset.x=sqrt((double) (mid*mid/(inverse_slope.q*inverse_slope.q+1.0))); + offset.y=(double) (offset.x*inverse_slope.q); +@@ -7659,8 +7802,8 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + theta.q=atan2(box_q[2].y-center.y,box_q[2].x-center.x); + if (theta.q < theta.p) + theta.q+=2.0*MagickPI; +- arc_segments=(size_t) CastDoubleToLong(ceil((double) ((theta.q- +- theta.p)/(2.0*sqrt(PerceptibleReciprocal(mid)))))); ++ arc_segments=(size_t) CastDoubleToSsizeT(ceil((double) ((theta.q- ++ theta.p)/(2.0*sqrt(MagickSafeReciprocal(mid)))))); + DisableMSCWarning(4127) + CheckPathExtent(MaxStrokePad,arc_segments+MaxStrokePad); + RestoreMSCWarning +@@ -7734,8 +7877,8 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + theta.q=atan2(box_p[2].y-center.y,box_p[2].x-center.x); + if (theta.p < theta.q) + theta.p+=2.0*MagickPI; +- arc_segments=(size_t) CastDoubleToLong(ceil((double) ((theta.p- +- theta.q)/(2.0*sqrt((double) (PerceptibleReciprocal(mid))))))); ++ arc_segments=(size_t) CastDoubleToSsizeT(ceil((double) ((theta.p- ++ theta.q)/(2.0*sqrt((double) (MagickSafeReciprocal(mid))))))); + DisableMSCWarning(4127) + CheckPathExtent(arc_segments+MaxStrokePad,MaxStrokePad); + RestoreMSCWarning +@@ -7771,7 +7914,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info, + Trace stroked polygon. + */ + stroke_polygon=(PrimitiveInfo *) AcquireQuantumMemory((size_t) +- (p+q+2L*closed_path+2L),sizeof(*stroke_polygon)); ++ (p+q+2L),(size_t) (closed_path+2L)*sizeof(*stroke_polygon)); + if (stroke_polygon == (PrimitiveInfo *) NULL) + { + (void) ThrowMagickException(exception,GetMagickModule(), diff -Nru imagemagick-7.1.1.43+dfsg1/debian/patches/series imagemagick-7.1.1.43+dfsg1/debian/patches/series --- imagemagick-7.1.1.43+dfsg1/debian/patches/series 2026-06-19 21:03:56.000000000 +0000 +++ imagemagick-7.1.1.43+dfsg1/debian/patches/series 2026-07-02 20:08:14.000000000 +0000 @@ -182,3 +182,27 @@ CVE-2026-53461.patch CVE-2026-53463.patch CVE-2026-53464.patch +CVE-2026-53466.patch +CVE-2026-53467.patch +draw-7.1.2-26.patch +draw-7.1.2-26-post1.patch +CVE-2026-55595.patch +CVE-2026-55597.patch +CVE-2026-55628-pre1.patch +CVE-2026-55628-pre2.patch +CVE-2026-55628-pre3.patch +CVE-2026-55628-pre4.patch +CVE-2026-55628.patch +CVE-2026-56361.patch +CVE-2026-56363.patch +CVE-2026-56364_1.patch +CVE-2026-56364_2.patch +CVE-2026-56365.patch +CVE-2026-56367.patch +CVE-2026-56368.patch +CVE-2026-56370.patch +CVE-2026-56371.patch +CVE-2026-56376.patch +CVE-2026-56377.patch +CVE-2026-56378_pre1.patch +CVE-2026-56378.patch