CVE-2016-10061
Description
ImageMagick's ReadGROUP4Image function in coders/tiff.c before 7.0.1-10 fails to check the return value of fputc, allowing a crafted file to cause a crash via denial of service.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
ImageMagick's ReadGROUP4Image function in coders/tiff.c before 7.0.1-10 fails to check the return value of fputc, allowing a crafted file to cause a crash via denial of service.
Vulnerability
The ReadGROUP4Image function in coders/tiff.c of ImageMagick before version 7.0.1-10 does not validate the return value of the fputc function when writing data to a temporary file during processing of a Group4-compressed TIFF image. This occurs in the loop that copies bytes from the image blob to the temporary file; if fputc fails (e.g., due to disk full or other I/O error), the unhandled failure can lead to undefined behavior such as a crash. The vulnerability is triggered when a crafted Group4 TIFF image is opened for reading, and the issue is confirmed in versions prior to the fix [1][2][4].
Exploitation
An attacker needs to deliver a specially crafted Group4 TIFF image file to a user or service that processes it using a vulnerable ImageMagick installation. No special privileges or authentication are required; the user or automated process must open the malformed image. The code path is reachable without any special configuration. The exploit sequence involves the ReadGROUP4Image function iterating over the image data and calling fputc without checking its return value; if an I/O error occurs during this loop, the unchecked failure can cause the program to crash [1][3][4].
Impact
Successful exploitation results in a denial of service (crash) of the ImageMagick process. The impact is limited to availability; there is no evidence of information disclosure, privilege escalation, or remote code execution. The crash can disrupt services that rely on ImageMagick to process user-supplied images [1][2][4].
Mitigation
The vulnerability is fixed in ImageMagick version 7.0.1-10 and later, as well as in the 6.x series with the appropriate patches. The fix was applied in commit 4e914bbe371433059f0cefdf3bd5f3a5710069f9, which adds proper error checking for fputc and destroys the image on failure [2][3]. Users should update to a patched version or apply the patch if using an older release. Red Hat has rated this issue as Low severity and does not plan to address it in future updates for its affected products [4]. No public KEV listing exists for this CVE.
AI Insight generated on May 23, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
13cpe:2.3:a:imagemagick:imagemagick:*:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:imagemagick:imagemagick:*:*:*:*:*:*:*:*range: <6.9.4-8
- (no CPE)range: <7.0.1-10
- osv-coords11 versionspkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Desktop%2012%20SP1pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Desktop%2012%20SP2pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP1pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP2pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Server%20for%20Raspberry%20Pi%2012%20SP2pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP1pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP2pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Software%20Development%20Kit%2012%20SP1pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Software%20Development%20Kit%2012%20SP2pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Workstation%20Extension%2012%20SP1pkg:rpm/suse/ImageMagick&distro=SUSE%20Linux%20Enterprise%20Workstation%20Extension%2012%20SP2
< 6.8.8.1-59.1+ 10 more
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
- (no CPE)range: < 6.8.8.1-59.1
Patches
231 file changed · +1 −1
ChangeLog+1 −1 modified@@ -1,5 +1,5 @@ 2016-06-05 6.9.4-8 Cristy <quetzlzacatenango@image...> - * Release ImageMagick version 6.9.4-8, GIT revision 18396:7590421:20160606. + * Release ImageMagick version 6.9.4-8, GIT revision 18406:ba4ad2d:20160607. 2016-06-04 6.9.4-8 Cristy <quetzlzacatenango@image...> * Deny indirect reads by policy, remove policy to permit, e.g.,
1 file changed · +1 −1
ChangeLog+1 −1 modified@@ -1,5 +1,5 @@ 2016-06-05 7.0.1-10 Cristy <quetzlzacatenango@image...> - * Release ImageMagick version 7.0.1-10, GIT revision 18396:7590421:20160606. + * Release ImageMagick version 7.0.1-10, GIT revision 18406:ba4ad2d:20160607. 2016-06-04 7.0.1-10 Cristy <quetzlzacatenango@image...> * Deny indirect reads by policy, remove policy to permit, e.g.,
4e914bbe3714https://github.com/ImageMagick/ImageMagick/issues/196
1 file changed · +5 −1
coders/tiff.c+5 −1 modified@@ -390,8 +390,10 @@ static Image *ReadGROUP4Image(const ImageInfo *image_info, length=fwrite("\000\000\000\000",1,4,file); length=WriteLSBLong(file,(long) image->resolution.x); length=WriteLSBLong(file,1); + status=MagickTrue; for (length=0; (c=ReadBlobByte(image)) != EOF; length++) - (void) fputc(c,file); + if (fputc(c,file) != c) + status=MagickFalse; offset=(ssize_t) fseek(file,(ssize_t) offset,SEEK_SET); length=WriteLSBLong(file,(unsigned int) length); (void) fclose(file); @@ -413,6 +415,8 @@ static Image *ReadGROUP4Image(const ImageInfo *image_info, (void) CopyMagickString(image->magick,"GROUP4",MagickPathExtent); } (void) RelinquishUniqueFileResource(filename); + if (status == MagickFalse) + image=DestroyImage(image); return(image); } #endif
56d6e20de489Prevent fault in MSL interpreter
2 files changed · +4 −0
ChangeLog+2 −0 modified@@ -1,6 +1,8 @@ 2016-11-01 6.9.6-4 Cristy <quetzlzacatenango@image...> * Off by one memory allocation (reference https://github.com/ImageMagick/ImageMagick/issues/296). + * Prevent fault in MSL interpreter (reference + https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=30797). 2016-10-30 6.9.6-3 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.6-3, GIT revision 11117:e857a26:20161030.
coders/msl.c+2 −0 modified@@ -4999,6 +4999,8 @@ static void MSLStartElement(void *context,const xmlChar *tag, Image *image; + if (value == (char *) NULL) + break; (void) CopyMagickString(msl_info->image_info[n]->filename, value,MaxTextExtent); image=ReadImage(msl_info->image_info[n],exception);
4ec444f4eab8Fixed memory leak.
1 file changed · +2 −0
coders/psd.c+2 −0 modified@@ -1719,6 +1719,8 @@ ModuleExport MagickBooleanType ReadPSDLayers(Image *image, if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), " layer data is empty"); + if (layer_info[i].info != (StringInfo *) NULL) + layer_info[i].info=DestroyStringInfo(layer_info[i].info); continue; }
f983dcdf9c17Fix TIFF divide by zero (bug report from Donghai Zhu)
2 files changed · +5 −3
ChangeLog+2 −2 modified@@ -3,8 +3,8 @@ pwchen&rayzhong of tencent). * Fix MSVG regression (reference https://github.com/ImageMagick/ImageMagick/issues/252). - * Prevent buffer overflow in SIXEL, PDB, MAP, and CALS coders (bug report - from Donghai Zhu). + * Prevent buffer overflow and other problems in SIXEL, PDB, MAP, TIFF, and + CALS coders (bug report from Donghai Zhu). 2016-08-14 6.9.5-7 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.5-7, GIT revision 10993:7d2fd25:20160814.
coders/tiff.c+3 −1 modified@@ -3469,7 +3469,9 @@ static MagickBooleanType WriteTIFFImage(const ImageInfo *image_info, if ((image_info->interlace == PlaneInterlace) || (image_info->interlace == PartitionInterlace)) (void) TIFFSetField(tiff,TIFFTAG_PLANARCONFIG,PLANARCONFIG_SEPARATE); - rows_per_strip=TIFFDefaultStripSize(tiff,0); + rows_per_strip=1; + if (TIFFScanlineSize(tiff) != 0) + rows_per_strip=TIFFDefaultStripSize(tiff,0); option=GetImageOption(image_info,"tiff:rows-per-strip"); if (option != (const char *) NULL) rows_per_strip=(size_t) strtol(option,(char **) NULL,10);
10b3823a7619Prevent buffer overflow in SIXEL, PDB, MAP, and CALS coders (bug report from Donghai Zhu)
5 files changed · +27 −23
ChangeLog+2 −0 modified@@ -3,6 +3,8 @@ pwchen&rayzhong of tencent). * Fix MSVG regression (reference https://github.com/ImageMagick/ImageMagick/issues/252). + * Prevent buffer overflow in SIXEL, PDB, MAP, and CALS coders (bug report + from Donghai Zhu). 2016-08-14 6.9.5-7 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.5-7, GIT revision 10993:7d2fd25:20160814.
coders/map.c+11 −10 modified@@ -401,22 +401,23 @@ static MagickBooleanType WriteMAPImage(const ImageInfo *image_info,Image *image) Write colormap to file. */ q=colormap; - if (image->depth <= 8) + q=colormap; + if (image->colors <= 256) for (i=0; i < (ssize_t) image->colors; i++) { - *q++=(unsigned char) image->colormap[i].red; - *q++=(unsigned char) image->colormap[i].green; - *q++=(unsigned char) image->colormap[i].blue; + *q++=(unsigned char) ScaleQuantumToChar(image->colormap[i].red); + *q++=(unsigned char) ScaleQuantumToChar(image->colormap[i].green); + *q++=(unsigned char) ScaleQuantumToChar(image->colormap[i].blue); } else for (i=0; i < (ssize_t) image->colors; i++) { - *q++=(unsigned char) ((size_t) image->colormap[i].red >> 8); - *q++=(unsigned char) image->colormap[i].red; - *q++=(unsigned char) ((size_t) image->colormap[i].green >> 8); - *q++=(unsigned char) image->colormap[i].green; - *q++=(unsigned char) ((size_t) image->colormap[i].blue >> 8); - *q++=(unsigned char) image->colormap[i].blue; + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].red) >> 8); + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].red) & 0xff); + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].green) >> 8); + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].green) & 0xff);; + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].blue) >> 8); + *q++=(unsigned char) (ScaleQuantumToShort(image->colormap[i].blue) & 0xff); } (void) WriteBlob(image,packet_size*image->colors,colormap); colormap=(unsigned char *) RelinquishMagickMemory(colormap);
coders/pdb.c+2 −1 modified@@ -825,7 +825,7 @@ static MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image) buffer=(unsigned char *) AcquireQuantumMemory(512,sizeof(*buffer)); if (buffer == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); - packet_size=(size_t) (image->depth > 8 ? 2: 1); + packet_size=(size_t) (image->depth > 8 ? 2 : 1); scanline=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size* sizeof(*scanline)); if (scanline == (unsigned char *) NULL) @@ -838,6 +838,7 @@ static MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image) quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); + status=SetQuantumDepth(image,quantum_info,image->depth > 8 ? 16 : 8); bits=8/(int) bits_per_pixel-1; /* start at most significant bits */ literal=0; repeat=0;
coders/sixel.c+11 −11 modified@@ -257,7 +257,7 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, imsx = 2048; imsy = 2048; - imbuf = (unsigned char *) AcquireQuantumMemory(imsx * imsy,1); + imbuf = (unsigned char *) AcquireQuantumMemory(imsx , imsy); if (imbuf == NULL) { return(MagickFalse); @@ -284,7 +284,7 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, sixel_palet[n] = SIXEL_RGB(255, 255, 255); } - (void) ResetMagickMemory(imbuf, background_color_index, imsx * imsy); + (void) ResetMagickMemory(imbuf, background_color_index, (size_t) imsx * imsy); while (*p != '\0') { if ((p[0] == '\033' && p[1] == 'P') || *p == 0x90) { @@ -358,14 +358,14 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, if (imsx < attributed_ph || imsy < attributed_pv) { dmsx = imsx > attributed_ph ? imsx : attributed_ph; dmsy = imsy > attributed_pv ? imsy : attributed_pv; - dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx * dmsy,1); + dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy); if (dmbuf == (unsigned char *) NULL) { imbuf = (unsigned char *) RelinquishMagickMemory(imbuf); return (MagickFalse); } - (void) ResetMagickMemory(dmbuf, background_color_index, dmsx * dmsy); + (void) ResetMagickMemory(dmbuf, background_color_index, (size_t) dmsx * dmsy); for (y = 0; y < imsy; ++y) { - (void) CopyMagickMemory(dmbuf + dmsx * y, imbuf + imsx * y, imsx); + (void) CopyMagickMemory(dmbuf + dmsx * y, imbuf + (size_t) imsx * y, imsx); } imbuf = (unsigned char *) RelinquishMagickMemory(imbuf); imsx = dmsx; @@ -432,14 +432,14 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, dmsx = nx; dmsy = ny; - dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx * dmsy,1); + dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy); if (dmbuf == (unsigned char *) NULL) { imbuf = (unsigned char *) RelinquishMagickMemory(imbuf); return (MagickFalse); } - (void) ResetMagickMemory(dmbuf, background_color_index, dmsx * dmsy); + (void) ResetMagickMemory(dmbuf, background_color_index, (size_t) dmsx * dmsy); for (y = 0; y < imsy; ++y) { - (void) CopyMagickMemory(dmbuf + dmsx * y, imbuf + imsx * y, imsx); + (void) CopyMagickMemory(dmbuf + dmsx * y, imbuf + (size_t) imsx * y, imsx); } imbuf = (unsigned char *) RelinquishMagickMemory(imbuf); imsx = dmsx; @@ -482,7 +482,7 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, c <<= 1; } for (y = posision_y + i; y < posision_y + i + n; ++y) { - (void) ResetMagickMemory(imbuf + imsx * y + posision_x, color_index, repeat_count); + (void) ResetMagickMemory(imbuf + (size_t) imsx * y + posision_x, color_index, repeat_count); } if (max_x < (posision_x + repeat_count - 1)) { max_x = posision_x + repeat_count - 1; @@ -515,7 +515,7 @@ MagickBooleanType sixel_decode(unsigned char /* in */ *p, if (imsx > max_x || imsy > max_y) { dmsx = max_x; dmsy = max_y; - if ((dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx * dmsy,1)) == NULL) { + if ((dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy)) == NULL) { imbuf = (unsigned char *) RelinquishMagickMemory(imbuf); return (MagickFalse); } @@ -1291,7 +1291,7 @@ static MagickBooleanType WriteSIXELImage(const ImageInfo *image_info,Image *imag Define SIXEL pixels. */ output = sixel_output_create(image); - sixel_pixels =(unsigned char *) AcquireQuantumMemory(image->columns * image->rows,1); + sixel_pixels =(unsigned char *) AcquireQuantumMemory(image->columns , image->rows); for (y=0; y < (ssize_t) image->rows; y++) { (void) GetVirtualPixels(image,0,y,image->columns,1,exception);
coders/tiff.c+1 −1 modified@@ -2492,8 +2492,8 @@ static MagickBooleanType WriteGROUP4Image(const ImageInfo *image_info, (void) SetImageType(huffman_image,BilevelType); write_info=CloneImageInfo((ImageInfo *) NULL); SetImageInfoFile(write_info,file); - (void) SetImageType(image,BilevelType); (void) SetImageDepth(image,1); + (void) SetImageType(image,BilevelType); write_info->compression=Group4Compression; write_info->type=BilevelType; (void) SetImageOption(write_info,"quantum:polarity","min-is-white");
9e187b73a8a1Changed the JPEG writer to raise a warning when the exif profile exceeds 65533 bytes and truncate it.
2 files changed · +11 −3
coders/jpeg.c+8 −3 modified@@ -1918,10 +1918,15 @@ static void WriteProfile(j_compress_ptr jpeg_info,Image *image) profile=GetImageProfile(image,name); p=GetStringInfoDatum(custom_profile); if (LocaleCompare(name,"EXIF") == 0) - for (i=0; i < (ssize_t) GetStringInfoLength(profile); i+=65533L) { - length=MagickMin(GetStringInfoLength(profile)-i,65533L); - jpeg_write_marker(jpeg_info,XML_MARKER,GetStringInfoDatum(profile)+i, + length=GetStringInfoLength(profile); + if (length > 65533L) + { + (void) ThrowMagickException(&image->exception,GetMagickModule(), + CoderWarning,"ExifProfileSizeExceedsLimit",image->filename); + length=65533L; + } + jpeg_write_marker(jpeg_info,XML_MARKER,GetStringInfoDatum(profile), (unsigned int) length); } if (LocaleCompare(name,"ICC") == 0)
config/english.xml+3 −0 modified@@ -205,6 +205,9 @@ </message> </error> <warning> + <message name="ExifProfileSizeExceedsLimit"> + exif profile size exceeds limit and will be truncated + </message> <message name="LosslessToLossyJPEGConversion"> lossless to lossy JPEG conversion </message>
ecc03a2518c2Prevent memory use after free
2 files changed · +2 −2
ChangeLog+2 −0 modified@@ -1,5 +1,7 @@ 2016-08-03 6.9.5-5 Cristy <quetzlzacatenango@image...> * Prevent buffer overflow (bug report from Max Thrane). + * Prevent memory use after free (reference + https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=30245). 2016-07-30 6.9.5-4 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.5-4, GIT revision 10973:a00fa93:20160729.
coders/pwp.c+0 −2 modified@@ -248,8 +248,6 @@ static Image *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) close(unique_file); (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); - (void) CloseBlob(pwp_image); - pwp_image=DestroyImage(pwp_image); if (EOFBlob(image) != MagickFalse) { char
989f9f88ea6dPrevent buffer overflow (bug report from Max Thrane)
2 files changed · +4 −1
ChangeLog+3 −0 modified@@ -1,3 +1,6 @@ +2016-08-03 6.9.5-5 Cristy <quetzlzacatenango@image...> + * Prevent buffer overflow (bug report from Max Thrane). + 2016-07-30 6.9.5-4 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.5-4, GIT revision 10973:a00fa93:20160729.
magick/draw.c+1 −1 modified@@ -2998,7 +2998,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info) } length++; } - length=length*BezierQuantum/2; + length=length*BezierQuantum; break; } case CirclePrimitive:
f8877abac8e5Improve buffer flow sanity check
1 file changed · +6 −7
coders/tiff.c+6 −7 modified@@ -62,6 +62,7 @@ #include "magick/log.h" #include "magick/magick.h" #include "magick/memory_.h" +#include "magick/memory-private.h" #include "magick/module.h" #include "magick/monitor.h" #include "magick/monitor-private.h" @@ -1903,14 +1904,13 @@ RestoreMSCWarning } (void) SetImageStorageClass(image,DirectClass); number_pixels=(MagickSizeType) columns*rows; - if ((number_pixels*sizeof(uint32)) != (MagickSizeType) ((size_t) - (number_pixels*sizeof(uint32)))) + if (HeapOverflowSanityCheck(rows,sizeof(*tile_pixels)) != MagickFalse) { TIFFClose(tiff); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } - tile_pixels=(uint32 *) AcquireQuantumMemory(number_pixels, - sizeof(*tile_pixels)); + tile_pixels=(uint32 *) AcquireQuantumMemory(columns, + rows*sizeof(*tile_pixels)); if (tile_pixels == (uint32 *) NULL) { TIFFClose(tiff); @@ -2012,14 +2012,13 @@ RestoreMSCWarning Convert TIFF image to DirectClass MIFF image. */ number_pixels=(MagickSizeType) image->columns*image->rows; - if ((number_pixels*sizeof(uint32)) != (MagickSizeType) ((size_t) - (number_pixels*sizeof(uint32)))) + if (HeapOverflowSanityCheck(image->rows,sizeof(*pixels)) != MagickFalse) { TIFFClose(tiff); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } pixel_info=AcquireVirtualMemory(image->columns,image->rows* - sizeof(uint32)); + sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) { TIFFClose(tiff);
1 file changed · +6 −6
coders/tiff.c+6 −6 modified@@ -1297,12 +1297,6 @@ RestoreMSCWarning image->columns=(size_t) width; image->rows=(size_t) height; image->depth=(size_t) bits_per_sample; - status=SetImageExtent(image,image->columns,image->rows); - if (status == MagickFalse) - { - InheritException(exception,&image->exception); - return(DestroyImageList(image)); - } if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Image depth: %.20g", (double) image->depth); @@ -1559,6 +1553,12 @@ RestoreMSCWarning } goto next_tiff_frame; } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } method=ReadGenericMethod; if (TIFFGetField(tiff,TIFFTAG_ROWSPERSTRIP,&rows_per_strip) == 1) {
73fb0aac5b95RLE check for pixel offset less than 0 (heap overflow report from Craig Young).
2 files changed · +8 −4
ChangeLog+2 −0 modified@@ -4,6 +4,8 @@ 2016-06-04 6.9.4-8 Cristy <quetzlzacatenango@image...> * Deny indirect reads by policy, remove policy to permit, e.g., convert caption:@mytext.txt ... + * RLE check for pixel offset less than 0 (heap overflow report from Craig + Young). 2016-06-03 6.9.4-7 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.4-7, GIT revision 10847:339f803:20160602.
coders/rle.c+6 −4 modified@@ -178,11 +178,11 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception) number_planes, number_planes_filled, one, - offset, pixel_info_length; ssize_t count, + offset, y; unsigned char @@ -395,7 +395,8 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception) offset=((image->rows-y-1)*image->columns*number_planes)+x* number_planes+plane; operand++; - if (offset+((size_t) operand*number_planes) > pixel_info_length) + if ((offset < 0) || + (offset+((size_t) operand*number_planes) > pixel_info_length)) { if (number_colormaps != 0) colormap=(unsigned char *) RelinquishMagickMemory(colormap); @@ -426,14 +427,15 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception) operand++; offset=((image->rows-y-1)*image->columns*number_planes)+x* number_planes+plane; - p=pixels+offset; - if (offset+((size_t) operand*number_planes) > pixel_info_length) + if ((offset < 0) || + (offset+((size_t) operand*number_planes) > pixel_info_length)) { if (number_colormaps != 0) colormap=(unsigned char *) RelinquishMagickMemory(colormap); pixel_info=RelinquishVirtualMemory(pixel_info); ThrowReaderException(CorruptImageError,"UnableToReadImageData"); } + p=pixels+offset; for (i=0; i < (ssize_t) operand; i++) { if ((y < (ssize_t) image->rows) &&
933e96f01a8chttps://github.com/ImageMagick/ImageMagick/issues/196
1 file changed · +19 −14
MagickWand/magick-cli.c+19 −14 modified@@ -636,12 +636,15 @@ static void MagickUsage(MagickBooleanType verbose) however the last argument provides the output filename. */ static MagickBooleanType ConcatenateImages(int argc,char **argv, - ExceptionInfo *exception ) + ExceptionInfo *exception ) { FILE *input, *output; + MagickBooleanType + status; + int c; @@ -650,29 +653,31 @@ static MagickBooleanType ConcatenateImages(int argc,char **argv, if (ExpandFilenames(&argc,&argv) == MagickFalse) ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed", - GetExceptionMessage(errno)); - + GetExceptionMessage(errno)); output=fopen_utf8(argv[argc-1],"wb"); - if (output == (FILE *) NULL) { - ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[argc-1]); - return(MagickFalse); - } - for (i=2; i < (ssize_t) (argc-1); i++) { -#if 0 - fprintf(stderr, "DEBUG: Concatenate Image: \"%s\"\n", argv[i]); -#endif + if (output == (FILE *) NULL) + { + ThrowFileException(exception,FileOpenError,"UnableToOpenFile", + argv[argc-1]); + return(MagickFalse); + } + status=MagickTrue; + for (i=2; i < (ssize_t) (argc-1); i++) + { input=fopen_utf8(argv[i],"rb"); - if (input == (FILE *) NULL) { + if (input == (FILE *) NULL) + { ThrowFileException(exception,FileOpenError,"UnableToOpenFile",argv[i]); continue; } for (c=fgetc(input); c != EOF; c=fgetc(input)) - (void) fputc((char) c,output); + if (fputc((char) c,output) != c) + status=MagickFalse; (void) fclose(input); (void) remove_utf8(argv[i]); } (void) fclose(output); - return(MagickTrue); + return(status); } WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc,
fc6080f1321fCoder path traversal is not authorized, bug report provided by Masaaki Chida
3 files changed · +18 −1
ChangeLog+5 −0 modified@@ -1,3 +1,8 @@ +2016-06-02 6.9.4-7 Cristy <quetzlzacatenango@image...> + * Fix small memory leak (patch provided by Андрей Черный). + * Coder path traversal is not authorized (bug report provided by + Masaaki Chida). + 2016-05-31 6.9.4-6 Cristy <quetzlzacatenango@image...> * Release ImageMagick version 6.9.4-6, GIT revision 18334:97775b5:20160531.
magick/module.c+9 −0 modified@@ -547,6 +547,15 @@ static MagickBooleanType GetMagickModulePath(const char *filename, assert(path != (char *) NULL); assert(exception != (ExceptionInfo *) NULL); (void) CopyMagickString(path,filename,MaxTextExtent); +#if defined(MAGICKCORE_INSTALLED_SUPPORT) + if (strstr(path,"../") != (char *) NULL) + { + errno=EPERM; + (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, + "NotAuthorized","`%s'",path); + return(MagickFalse); + } +#endif module_path=(char *) NULL; switch (module_type) {
magick/xml-tree.c+4 −1 modified@@ -2140,7 +2140,10 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception) if ((ignore_depth == 0) && (IsSkipTag(tag) == MagickFalse)) ParseOpenTag(root,tag,attributes); else - ignore_depth++; + { + ignore_depth++; + (void) DestroyXMLTreeAttributes(attributes); + } *p=c; } else
0474237508f3Suspend exception processing if there are too many exceptions
5 files changed · +76 −48
coders/label.c+7 −5 modified@@ -136,7 +136,7 @@ static Image *ReadLABELImage(const ImageInfo *image_info, status=GetMultilineTypeMetrics(image,draw_info,&metrics); if ((image->columns == 0) && (image->rows == 0)) { - image->columns=(size_t) (metrics.width+draw_info->stroke_width+0.5); + image->columns=(size_t) floor(metrics.width+draw_info->stroke_width+0.5); image->rows=(size_t) floor(metrics.height+draw_info->stroke_width+0.5); } else @@ -205,14 +205,16 @@ static Image *ReadLABELImage(const ImageInfo *image_info, return((Image *) NULL); } if (image->columns == 0) - image->columns=(size_t) (metrics.width+draw_info->stroke_width+0.5); + image->columns=(size_t) floor(metrics.width+draw_info->stroke_width+0.5); if (image->columns == 0) - image->columns=(size_t) (draw_info->pointsize+draw_info->stroke_width+0.5); + image->columns=(size_t) floor(draw_info->pointsize+draw_info->stroke_width+ + 0.5); if (image->rows == 0) - image->rows=(size_t) (metrics.ascent-metrics.descent+ + image->rows=(size_t) floor(metrics.ascent-metrics.descent+ draw_info->stroke_width+0.5); if (image->rows == 0) - image->rows=(size_t) (draw_info->pointsize+draw_info->stroke_width+0.5); + image->rows=(size_t) floor(draw_info->pointsize+draw_info->stroke_width+ + 0.5); status=SetImageExtent(image,image->columns,image->rows); if (status == MagickFalse) {
coders/viff.c+2 −18 modified@@ -137,22 +137,6 @@ static MagickBooleanType IsVIFF(const unsigned char *magick,const size_t length) % o exception: return any errors or warnings in this structure. % */ - -static MagickBooleanType CheckMemoryOverflow(const size_t count, - const size_t quantum) -{ - size_t - size; - - size=count*quantum; - if ((count == 0) || (quantum != (size/count))) - { - errno=ENOMEM; - return(MagickTrue); - } - return(MagickFalse); -} - static Image *ReadVIFFImage(const ImageInfo *image_info, ExceptionInfo *exception) { @@ -520,13 +504,13 @@ static Image *ReadVIFFImage(const ImageInfo *image_info, } if (viff_info.data_storage_type == VFF_TYP_BIT) { - if (CheckMemoryOverflow((image->columns+7UL) >> 3UL,image->rows) != MagickFalse) + if (HeapOverflowSanityCheck((image->columns+7UL) >> 3UL,image->rows) != MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); max_packets=((image->columns+7UL) >> 3UL)*image->rows; } else { - if (CheckMemoryOverflow(number_pixels,viff_info.number_data_bands) != MagickFalse) + if (HeapOverflowSanityCheck(number_pixels,viff_info.number_data_bands) != MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); max_packets=(size_t) (number_pixels*viff_info.number_data_bands); }
magick/exception.c+21 −5 modified@@ -52,6 +52,11 @@ #include "magick/string_.h" #include "magick/utility.h" +/* + Global declarations. +*/ +#define MaxExceptions 128 + /* Forward declarations. */ @@ -193,6 +198,9 @@ MagickExport void CatchException(ExceptionInfo *exception) register const ExceptionInfo *p; + ssize_t + i; + assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if (exception->exceptions == (void *) NULL) @@ -201,14 +209,22 @@ MagickExport void CatchException(ExceptionInfo *exception) ResetLinkedListIterator((LinkedListInfo *) exception->exceptions); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); - while (p != (const ExceptionInfo *) NULL) + for (i=0; p != (const ExceptionInfo *) NULL; i++) { - if ((p->severity >= WarningException) && (p->severity < ErrorException)) - MagickWarning(p->severity,p->reason,p->description); - if ((p->severity >= ErrorException) && (p->severity < FatalErrorException)) - MagickError(p->severity,p->reason,p->description); if (p->severity >= FatalErrorException) MagickFatalError(p->severity,p->reason,p->description); + if (i < MaxExceptions) + { + if ((p->severity >= ErrorException) && + (p->severity < FatalErrorException)) + MagickError(p->severity,p->reason,p->description); + if ((p->severity >= WarningException) && (p->severity < ErrorException)) + MagickWarning(p->severity,p->reason,p->description); + } + else + if (i == MaxExceptions) + MagickError(ResourceLimitError,"too many exceptions", + "exception processing suspended"); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); }
magick/memory.c+43 −20 modified@@ -234,22 +234,6 @@ static MagickBooleanType % o quantum: the number of bytes in each quantum. % */ - -static MagickBooleanType CheckMemoryOverflow(const size_t count, - const size_t quantum) -{ - size_t - size; - - size=count*quantum; - if ((count == 0) || (quantum != (size/count))) - { - errno=ENOMEM; - return(MagickTrue); - } - return(MagickFalse); -} - MagickExport void *AcquireAlignedMemory(const size_t count,const size_t quantum) { #define AlignedExtent(size,alignment) \ @@ -263,7 +247,7 @@ MagickExport void *AcquireAlignedMemory(const size_t count,const size_t quantum) void *memory; - if (CheckMemoryOverflow(count,quantum) != MagickFalse) + if (HeapOverflowSanityCheck(count,quantum) != MagickFalse) return((void *) NULL); memory=NULL; alignment=CACHE_LINE_SIZE; @@ -544,7 +528,7 @@ MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum) size_t extent; - if (CheckMemoryOverflow(count,quantum) != MagickFalse) + if (HeapOverflowSanityCheck(count,quantum) != MagickFalse) return((void *) NULL); extent=count*quantum; return(AcquireMagickMemory(extent)); @@ -584,7 +568,7 @@ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, size_t extent; - if (CheckMemoryOverflow(count,quantum) != MagickFalse) + if (HeapOverflowSanityCheck(count,quantum) != MagickFalse) return((MemoryInfo *) NULL); memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, sizeof(*memory_info))); @@ -917,6 +901,45 @@ MagickExport void *GetVirtualMemoryBlob(const MemoryInfo *memory_info) % % % % % % ++ H e a p O v e r f l o w S a n i t y C h e c k % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% HeapOverflowSanityCheck() returns MagickTrue if the heap allocation request +% does not exceed the maximum limits of a size_t otherwise MagickFalse. +% +% The format of the HeapOverflowSanityCheck method is: +% +% MagickBooleanType HeapOverflowSanityCheck(const size_t count, +% const size_t quantum) +% +% A description of each parameter follows: +% +% o size: the size of the memory in bytes we require. +% +*/ +MagickExport MagickBooleanType HeapOverflowSanityCheck(const size_t count, + const size_t quantum) +{ + size_t + size; + + size=count*quantum; + if ((count == 0) || (quantum != (size/count))) + { + errno=ENOMEM; + return(MagickTrue); + } + return(MagickFalse); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % R e l i n q u i s h A l i g n e d M e m o r y % % % % % @@ -1222,7 +1245,7 @@ MagickExport void *ResizeQuantumMemory(void *memory,const size_t count, size_t extent; - if (CheckMemoryOverflow(count,quantum) != MagickFalse) + if (HeapOverflowSanityCheck(count,quantum) != MagickFalse) { memory=RelinquishMagickMemory(memory); return((void *) NULL);
magick/memory-private.h+3 −0 modified@@ -41,6 +41,9 @@ extern "C" { #define MagickAssumeAligned(address) (address) #endif +MagickExport MagickBooleanType + HeapOverflowSanityCheck(const size_t,const size_t) magick_alloc_sizes(1,2); + #if defined(__cplusplus) || defined(c_plusplus) } #endif
8a370f9ab120Added check for invalid number of frames.
1 file changed · +3 −1
coders/mat.c+3 −1 modified@@ -942,7 +942,9 @@ MATLAB_KO: ThrowReaderException(CorruptImageError,"ImproperImageHeader"); case 16: z2=z = ReadBlobXXXLong(image2); /* 4D matrix animation */ if(z!=3 && z!=1) ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported"); - Frames = ReadBlobXXXLong(image2); + Frames = ReadBlobXXXLong(image2); + if (Frames == 0) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); break; default: ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported"); }
3e9165285edahttps://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29710
1 file changed · +3 −2
coders/rle.c+3 −2 modified@@ -322,10 +322,11 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception) number_planes_filled)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixel_info=AcquireVirtualMemory(image->columns,image->rows* - number_planes_filled*sizeof(*pixels)); + MagickMax(number_planes_filled,4)*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); - pixel_info_length=image->columns*image->rows*number_planes_filled; + pixel_info_length=image->columns*image->rows* + MagickMax(number_planes_filled,4); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); if ((flags & 0x01) && !(flags & 0x02)) {
2 files changed · +8 −6
coders/jpeg.c+1 −2 modified@@ -1229,8 +1229,7 @@ static Image *ReadJPEGImage(const ImageInfo *image_info, if (option != (const char *) NULL) if (AcquireImageColormap(image,StringToUnsignedLong(option)) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); - if ((jpeg_info.output_components == 1) && - (jpeg_info.quantize_colors == 0)) + if ((jpeg_info.output_components == 1) && (jpeg_info.quantize_colors == 0)) { size_t colors;
coders/tiff.c+7 −4 modified@@ -1888,9 +1888,6 @@ RestoreMSCWarning columns, rows; - size_t - number_pixels; - /* Convert tiled TIFF image to DirectClass MIFF image. */ @@ -1901,7 +1898,13 @@ RestoreMSCWarning ThrowReaderException(CoderError,"ImageIsNotTiled"); } (void) SetImageStorageClass(image,DirectClass); - number_pixels=columns*rows; + number_pixels=(MagickSizeType) columns*rows; + if ((number_pixels*sizeof(uint32)) != (MagickSizeType) ((size_t) + (number_pixels*sizeof(uint32)))) + { + TIFFClose(tiff); + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } tile_pixels=(uint32 *) AcquireQuantumMemory(number_pixels, sizeof(*tile_pixels)); if (tile_pixels == (uint32 *) NULL)
b173a3523978https://github.com/ImageMagick/ImageMagick/issues/131
1 file changed · +1 −0
coders/mat.c+1 −0 modified@@ -936,6 +936,7 @@ RestoreMSCWarning } } } while(z-- >= 2); + quantum_info=DestroyQuantumInfo(quantum_info); ExitLoop:
134463b926fahttps://github.com/ImageMagick/ImageMagick/issues/129
3 files changed · +30 −4
coders/viff.c+28 −4 modified@@ -137,6 +137,22 @@ static MagickBooleanType IsVIFF(const unsigned char *magick,const size_t length) % o exception: return any errors or warnings in this structure. % */ + +static MagickBooleanType CheckMemoryOverflow(const size_t count, + const size_t quantum) +{ + size_t + size; + + size=count*quantum; + if ((count == 0) || (quantum != (size/count))) + { + errno=ENOMEM; + return(MagickTrue); + } + return(MagickFalse); +} + static Image *ReadVIFFImage(const ImageInfo *image_info, ExceptionInfo *exception) { @@ -475,7 +491,7 @@ static Image *ReadVIFFImage(const ImageInfo *image_info, /* Initialize image structure. */ - image->alpha_trait=viff_info.number_data_bands == 4 ? BlendPixelTrait : + image->alpha_trait=viff_info.number_data_bands == 4 ? BlendPixelTrait : UndefinedPixelTrait; image->storage_class=(viff_info.number_data_bands < 3 ? PseudoClass : DirectClass); @@ -499,9 +515,17 @@ static Image *ReadVIFFImage(const ImageInfo *image_info, default: bytes_per_pixel=1; break; } if (viff_info.data_storage_type == VFF_TYP_BIT) - max_packets=((image->columns+7UL) >> 3UL)*image->rows; + { + if (CheckMemoryOverflow((image->columns+7UL) >> 3UL,image->rows) != MagickFalse) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + max_packets=((image->columns+7UL) >> 3UL)*image->rows; + } else - max_packets=(size_t) (number_pixels*viff_info.number_data_bands); + { + if (CheckMemoryOverflow(number_pixels,viff_info.number_data_bands) != MagickFalse) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + max_packets=(size_t) (number_pixels*viff_info.number_data_bands); + } pixels=(unsigned char *) AcquireQuantumMemory(MagickMax(number_pixels, max_packets),bytes_per_pixel*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) @@ -695,7 +719,7 @@ static Image *ReadVIFFImage(const ImageInfo *image_info, { ssize_t index; - + index=(ssize_t) GetPixelRed(image,q); SetPixelRed(image,image->colormap[ ConstrainColormapIndex(image,index,exception)].red,q);
MagickCore/memory.c+1 −0 modified@@ -233,6 +233,7 @@ static MagickBooleanType % o quantum: the number of bytes in each quantum. % */ + static MagickBooleanType CheckMemoryOverflow(const size_t count, const size_t quantum) {
MagickCore/quantum-import.c+1 −0 modified@@ -2024,6 +2024,7 @@ static void ImportGrayQuantum(const Image *image,QuantumInfo *quantum_info, assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); + pixel=0; switch (quantum_info->depth) { case 1:
f3b483e8b054https://github.com/ImageMagick/ImageMagick/issues/131
1 file changed · +1 −1
coders/mat.c+1 −1 modified@@ -875,7 +875,7 @@ RestoreMSCWarning } /* ----- Load raster data ----- */ - BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(unsigned char)); /* Ldblk was set in the check phase */ + BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(double)); /* Ldblk was set in the check phase */ if (BImgBuff == NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
f6e9d0d9955e84 files changed · +541 −15
ChangeLog+2 −0 modified@@ -22,6 +22,8 @@ Mateusz Jurczyk of the Google Security Team). * Additional PNM sanity checks (reference http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=26682). + * The SetImageBias() biad value is no longer ignored (reference + http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=25732). 2014-11-16 6.9.0-0 Cristy <quetzlzacatenango@image...> * New version 6.9.0-0, SVN revision 17067.
coders/aai.c+6 −0 modified@@ -158,6 +158,12 @@ static Image *ReadAAIImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } pixels=(unsigned char *) AcquireQuantumMemory(image->columns, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL)
coders/art.c+6 −0 modified@@ -155,6 +155,12 @@ static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert bi-level image to pixel packets. */
coders/avs.c+6 −0 modified@@ -160,6 +160,12 @@ static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } pixels=(unsigned char *) AcquireQuantumMemory(image->columns, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL)
coders/bgr.c+6 −0 modified@@ -197,6 +197,12 @@ static Image *ReadBGRImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } switch (image_info->interlace) { case NoInterlace:
coders/bmp.c+6 −0 modified@@ -928,6 +928,12 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read image data. */
coders/cin.c+7 −1 modified@@ -721,11 +721,17 @@ static Image *ReadCINImage(const ImageInfo *image_info,ExceptionInfo *exception) image->depth=cin.image.channel[0].bits_per_pixel; image->columns=cin.image.channel[0].pixels_per_line; image->rows=cin.image.channel[0].lines_per_image; - if (image_info->ping) + if (image_info->ping != MagickFalse) { (void) CloseBlob(image); return(image); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert CIN raster image to pixel packets. */
coders/clipboard.c+8 −2 modified@@ -136,7 +136,7 @@ static Image *ReadCLIPBOARDImage(const ImageInfo *image_info, bitmapH=(HBITMAP) GetClipboardData(CF_BITMAP); hPal=(HPALETTE) GetClipboardData(CF_PALETTE); CloseClipboard(); - if ( bitmapH == NULL ) + if (bitmapH == NULL) ThrowReaderException(CoderError,"NoBitmapOnClipboard"); { BITMAPINFO @@ -163,8 +163,14 @@ static Image *ReadCLIPBOARDImage(const ImageInfo *image_info, GetObject(bitmapH,sizeof(BITMAP),(LPSTR) &bitmap); if ((image->columns == 0) || (image->rows == 0)) { - image->rows=bitmap.bmHeight; image->columns=bitmap.bmWidth; + image->rows=bitmap.bmHeight; + } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); } /* Initialize the bitmap header info.
coders/cmyk.c+6 −0 modified@@ -197,6 +197,12 @@ static Image *ReadCMYKImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } SetImageColorspace(image,CMYKColorspace); switch (image_info->interlace) {
coders/cut.c+7 −1 modified@@ -371,7 +371,13 @@ static Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception) image->depth=8; image->colors=(size_t) (GetQuantumRange(1UL*i)+1); - if (image_info->ping) goto Finish; + if (image_info->ping != MagickFalse) goto Finish; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* ----- Do something with palette ----- */ if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
coders/dcm.c+6 −0 modified@@ -3689,6 +3689,12 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=(size_t) width; image->rows=(size_t) height; image->depth=depth; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + break; + } image->colorspace=RGBColorspace; if ((image->colormap == (PixelPacket *) NULL) && (samples_per_pixel == 1)) {
coders/dds.c+6 −0 modified@@ -1834,6 +1834,12 @@ static Image *ReadDDSImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if ((decoder)(image, &dds_info, exception) != MagickTrue) {
coders/dib.c+7 −1 modified@@ -520,7 +520,7 @@ static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception) */ (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info)); dib_info.size=ReadBlobLSBLong(image); - if (dib_info.size!=40) + if (dib_info.size != 40) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); /* Microsoft Windows 3.X DIB image file. @@ -573,6 +573,12 @@ static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((geometry.height != 0) && (geometry.height < image->rows)) image->rows=geometry.height; } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (image->storage_class == PseudoClass) { size_t
coders/djvu.c+8 −1 modified@@ -418,7 +418,7 @@ get_page_image(LoadContext *lc, ddjvu_page_t *page, int x, int y, int w, int h, if (SyncAuthenticPixels(image,&image->exception) == MagickFalse) break; } - if (!image->ping) + if (image->ping == MagickFalse) SyncImage(image); } else { #if DEBUG @@ -577,6 +577,7 @@ static Image *ReadOneDJVUImage(LoadContext* lc,const int pagenum, Image *image; int logging; int tag; + MagickBooleanType status; /* so, we know that the page is there! Get its dimension, and */ @@ -667,6 +668,12 @@ static Image *ReadOneDJVUImage(LoadContext* lc,const int pagenum, image->matte = MagickTrue; /* is this useful? */ } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } #if DEBUG printf("now filling %.20g x %.20g\n",(double) image->columns,(double) image->rows);
coders/dps.c+6 −0 modified@@ -328,6 +328,12 @@ static Image *ReadDPSImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } switch (image->storage_class) { case DirectClass:
coders/dpx.c+6 −0 modified@@ -1126,6 +1126,12 @@ static Image *ReadDPXImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } for (n=0; n < (ssize_t) dpx.image.number_elements; n++) { /*
coders/emf.c+6 −0 modified@@ -507,6 +507,12 @@ static Image *ReadEMFImage(const ImageInfo *image_info, y=0; (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (image_info->page != (char *) NULL) { char
coders/exr.c+6 −0 modified@@ -212,6 +212,12 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } scanline=(ImfRgba *) AcquireQuantumMemory(image->columns,sizeof(*scanline)); if (scanline == (ImfRgba *) NULL) {
coders/fax.c+6 −0 modified@@ -178,6 +178,12 @@ static Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } status=HuffmanDecodeImage(image); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"UnableToReadImageData");
coders/fits.c+6 −0 modified@@ -423,6 +423,12 @@ static Image *ReadFITSImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Initialize image structure. */
coders/fpx.c+6 −0 modified@@ -352,6 +352,12 @@ static Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception) FPX_ClearSystem(); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate memory for the image and pixel buffer. */
coders/gif.c+6 −0 modified@@ -1350,6 +1350,12 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Decode image. */
coders/gray.c+6 −0 modified@@ -187,6 +187,12 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } SetImageColorspace(image,GRAYColorspace); if (scene == 0) {
coders/hald.c+7 −2 modified@@ -125,6 +125,12 @@ static Image *ReadHALDImage(const ImageInfo *image_info, cube_size=level*level; image->columns=(size_t) (level*cube_size); image->rows=(size_t) (level*cube_size); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) level) { ssize_t @@ -137,8 +143,7 @@ static Image *ReadHALDImage(const ImageInfo *image_info, if (status == MagickFalse) continue; - q=QueueAuthenticPixels(image,0,y,image->columns,(size_t) level, - exception); + q=QueueAuthenticPixels(image,0,y,image->columns,(size_t) level,exception); if (q == (PixelPacket *) NULL) { status=MagickFalse;
coders/hdr.c+6 −0 modified@@ -382,6 +382,12 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read RGBE (red+green+blue+exponent) pixels. */
coders/hrz.c+6 −0 modified@@ -142,6 +142,12 @@ static Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=256; image->rows=240; image->depth=8; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } pixels=(unsigned char *) AcquireQuantumMemory(image->columns,3* sizeof(*pixels)); if (pixels == (unsigned char *) NULL)
coders/icon.c+6 −0 modified@@ -462,6 +462,12 @@ static Image *ReadICONImage(const ImageInfo *image_info, (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } bytes_per_line=(((image->columns*icon_info.bits_per_pixel)+31) & ~31) >> 3; (void) bytes_per_line;
coders/ipl.c+7 −1 modified@@ -315,9 +315,15 @@ static Image *ReadIPLImage(const ImageInfo *image_info,ExceptionInfo *exception) { SetHeaderFromIPL(image, &ipl_info); - if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) + if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* printf("Length: %.20g, Memory size: %.20g\n", (double) length,(double) image->depth);
coders/jbig.c+6 −0 modified@@ -219,6 +219,12 @@ static Image *ReadJBIGImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert X bitmap image to pixel packets. */
coders/jp2.c+6 −0 modified@@ -398,6 +398,12 @@ static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=(size_t) jp2_image->comps[0].w; image->rows=(size_t) jp2_image->comps[0].h; image->depth=jp2_image->comps[0].prec; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } image->compression=JPEG2000Compression; if (jp2_image->numcomps <= 2) {
coders/jpeg.c+6 −0 modified@@ -1263,6 +1263,12 @@ static Image *ReadJPEGImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } memory_info=AcquireVirtualMemory((size_t) image->columns, jpeg_info.output_components*sizeof(*jpeg_pixels)); if (memory_info == (MemoryInfo *) NULL)
coders/label.c+6 −0 modified@@ -213,6 +213,12 @@ static Image *ReadLABELImage(const ImageInfo *image_info, draw_info->stroke_width+0.5); if (image->rows == 0) image->rows=(size_t) (draw_info->pointsize+draw_info->stroke_width+0.5); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (draw_info->gravity == UndefinedGravity) { (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
coders/mac.c+6 −0 modified@@ -156,6 +156,12 @@ static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert MAC raster image to pixel packets. */
coders/map.c+6 −0 modified@@ -206,6 +206,12 @@ static Image *ReadMAPImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read image pixels. */
coders/mat.c+6 −0 modified@@ -874,6 +874,12 @@ RestoreMSCWarning image->rows = temp; goto done_reading; /* !!!!!! BAD !!!! */ } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* ----- Load raster data ----- */ BImgBuff = (unsigned char *) AcquireQuantumMemory((size_t) (ldblk),sizeof(unsigned char)); /* Ldblk was set in the check phase */
coders/miff.c+6 −0 modified@@ -1246,6 +1246,12 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate image pixels. */
coders/mono.c+6 −0 modified@@ -154,6 +154,12 @@ static Image *ReadMONOImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert bi-level image to pixel packets. */
coders/mpc.c+6 −0 modified@@ -929,6 +929,12 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Attach persistent pixel cache. */
coders/mtv.c+6 −0 modified@@ -158,6 +158,12 @@ static Image *ReadMTVImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert MTV raster image to pixel packets. */
coders/mvg.c+6 −0 modified@@ -190,6 +190,12 @@ static Image *ReadMVGImage(const ImageInfo *image_info,ExceptionInfo *exception) DefaultResolution; image->columns=(size_t) (draw_info->affine.sx*image->columns); image->rows=(size_t) (draw_info->affine.sy*image->rows); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (SetImageBackgroundColor(image) == MagickFalse) { InheritException(exception,&image->exception);
coders/null.c+9 −0 modified@@ -99,6 +99,9 @@ static Image *ReadNULLImage(const ImageInfo *image_info, Image *image; + MagickBooleanType + status; + MagickPixelPacket background; @@ -129,6 +132,12 @@ static Image *ReadNULLImage(const ImageInfo *image_info, image->columns=1; if (image->rows == 0) image->rows=1; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } image->matte=MagickTrue; GetMagickPixelPacket(image,&background); background.opacity=(MagickRealType) TransparentOpacity;
coders/otb.c+6 −0 modified@@ -168,6 +168,12 @@ static Image *ReadOTBImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert bi-level image to pixel packets. */
coders/palm.c+6 −0 modified@@ -329,6 +329,12 @@ static Image *ReadPALMImage(const ImageInfo *image_info, ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize"); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } bytes_per_row=ReadBlobMSBShort(image); flags=ReadBlobMSBShort(image); bits_per_pixel=(size_t) ReadBlobByte(image);
coders/pango.c+8 −2 modified@@ -375,11 +375,17 @@ static Image *ReadPANGOImage(const ImageInfo *image_info, (image->y_resolution == 0.0 ? 90.0 : image->y_resolution)+45.0)/90.0+ 0.5)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Render markup. */ - stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, - (int) image->columns); + stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,(int) + image->columns); pixel_info=AcquireVirtualMemory(image->rows,stride*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) {
coders/pcd.c+6 −0 modified@@ -594,6 +594,12 @@ static Image *ReadPCDImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns<<=1; image->rows<<=1; } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate luma and chroma memory. */
coders/pcx.c+6 −0 modified@@ -395,6 +395,12 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read image data. */
coders/pdb.c+6 −0 modified@@ -402,6 +402,12 @@ static Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } packets=(bits_per_pixel*image->columns+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(packets+256UL,image->rows* sizeof(*pixels));
coders/pict.c+6 −0 modified@@ -922,6 +922,12 @@ static Image *ReadPICTImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if ((version == 1) || ((TellBlob(image) % 2) != 0)) code=ReadBlobByte(image); if (version == 2)
coders/pix.c+6 −0 modified@@ -161,6 +161,12 @@ static Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert PIX raster image to pixel packets. */
coders/psd.c+6 −0 modified@@ -1653,6 +1653,12 @@ static Image *ReadPSDImage(const ImageInfo *image_info, image->depth=psd_info.depth; image->columns=psd_info.columns; image->rows=psd_info.rows; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (SetImageBackgroundColor(image) == MagickFalse) { InheritException(exception,&image->exception);
coders/raw.c+6 −0 modified@@ -180,6 +180,12 @@ static Image *ReadRAWImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
coders/rgb.c+6 −0 modified@@ -201,6 +201,12 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } switch (image_info->interlace) { case NoInterlace:
coders/rgf.c+6 −2 modified@@ -172,8 +172,12 @@ static Image *ReadRGFImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } - - + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read hex image data. */
coders/rla.c+6 −0 modified@@ -261,6 +261,12 @@ static Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } scanlines=(ssize_t *) AcquireQuantumMemory(image->rows,sizeof(*scanlines)); if (scanlines == (ssize_t *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
coders/rle.c+6 −0 modified@@ -293,6 +293,12 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate RLE pixels. */
coders/scr.c+6 −0 modified@@ -156,6 +156,12 @@ static Image *ReadSCRImage(const ImageInfo *image_info,ExceptionInfo *exception) } image->columns = 256; image->rows = 192; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } count=ReadBlob(image,6144,(unsigned char *) zxscr); (void) count; count=ReadBlob(image,768,(unsigned char *) zxattr);
coders/screenshot.c+9 −1 modified@@ -133,6 +133,9 @@ static Image *ReadSCREENSHOTImage(const ImageInfo *image_info, int i; + MagickBooleanType + status; + register PixelPacket *q; @@ -162,7 +165,12 @@ static Image *ReadSCREENSHOTImage(const ImageInfo *image_info, screen->columns=(size_t) GetDeviceCaps(hDC,HORZRES); screen->rows=(size_t) GetDeviceCaps(hDC,VERTRES); screen->storage_class=DirectClass; - + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (image == (Image *) NULL) image=screen; else
coders/sct.c+6 −0 modified@@ -224,6 +224,12 @@ static Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert SCT raster image to pixel packets. */
coders/sgi.c+6 −0 modified@@ -374,6 +374,12 @@ static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate SGI pixels. */
coders/sixel.c+6 −1 modified@@ -1027,7 +1027,12 @@ static Image *ReadSIXELImage(const ImageInfo *image_info,ExceptionInfo *exceptio sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer); image->depth=24; image->storage_class=PseudoClass; - + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (AcquireImageColormap(image,image->colors) == MagickFalse) { sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
coders/stegano.c+6 −0 modified@@ -169,6 +169,12 @@ static Image *ReadSTEGANOImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Get hidden watermark from low-order bits of image. */
coders/sun.c+6 −0 modified@@ -412,6 +412,12 @@ static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if ((sun_info.length*sizeof(*sun_data))/sizeof(*sun_data) != sun_info.length || !sun_info.length) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
coders/svg.c+6 −0 modified@@ -2945,6 +2945,12 @@ static Image *ReadSVGImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=gdk_pixbuf_get_width(pixel_buffer); image->rows=gdk_pixbuf_get_height(pixel_buffer); #endif + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } image->matte=MagickTrue; SetImageProperty(image,"svg:base-uri", rsvg_handle_get_base_uri(svg_handle));
coders/tga.c+6 −0 modified@@ -307,6 +307,12 @@ static Image *ReadTGAImage(const ImageInfo *image_info, (void) CloseBlob(image); return(image); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } (void) ResetMagickMemory(&pixel,0,sizeof(pixel)); pixel.opacity=(Quantum) OpaqueOpacity; if (tga_info.colormap_type != 0)
coders/tiff.c+6 −0 modified@@ -1195,6 +1195,12 @@ RestoreMSCWarning image->columns=(size_t) width; image->rows=(size_t) height; image->depth=(size_t) bits_per_sample; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Image depth: %.20g", (double) image->depth);
coders/tile.c+9 −0 modified@@ -95,6 +95,9 @@ static Image *ReadTILEImage(const ImageInfo *image_info, ImageInfo *read_info; + MagickBooleanType + status; + /* Initialize Image structure. */ @@ -115,6 +118,12 @@ static Image *ReadTILEImage(const ImageInfo *image_info, image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (*image_info->filename == '\0') ThrowReaderException(OptionError,"MustSpecifyAnImageName"); image->colorspace=tile_image->colorspace;
coders/tim.c+6 −0 modified@@ -223,6 +223,12 @@ static Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read image data. */
coders/ttf.c+6 −0 modified@@ -225,6 +225,12 @@ static Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception) image=DestroyImageList(image); return((Image *) NULL); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Color canvas with background color */
coders/txt.c+12 −0 modified@@ -228,6 +228,12 @@ static Image *ReadTEXTImage(const ImageInfo *image_info,Image *image, delta.x)+0.5); image->rows=(size_t) floor((((double) page.height*image->y_resolution)/ delta.y)+0.5); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } image->page.x=0; image->page.y=0; texture=(Image *) NULL; @@ -437,6 +443,12 @@ static Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception) image->rows=height; for (depth=1; (GetQuantumRange(depth)+1) < max_value; depth++) ; image->depth=depth; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } LocaleLower(colorspace); i=(ssize_t) strlen(colorspace)-1; image->matte=MagickFalse;
coders/uyvy.c+6 −0 modified@@ -145,6 +145,12 @@ static Image *ReadUYVYImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Accumulate UYVY, then unpack into two pixels. */
coders/vicar.c+6 −0 modified@@ -285,6 +285,12 @@ static Image *ReadVICARImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Read VICAR pixels. */
coders/viff.c+6 −0 modified@@ -478,6 +478,12 @@ static Image *ReadVIFFImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Allocate VIFF pixels. */
coders/vips.c+6 −0 modified@@ -416,6 +416,12 @@ static Image *ReadVIPSImage(const ImageInfo *image_info, ThrowReaderException(CorruptImageError,"ImproperImageHeader"); image->columns=(size_t) ReadBlobLong(image); image->rows=(size_t) ReadBlobLong(image); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } channels=ReadBlobLong(image); (void) ReadBlobLong(image); /* Legacy */ format=(VIPSBandFormat) ReadBlobLong(image);
coders/wbmp.c+6 −0 modified@@ -185,6 +185,12 @@ static Image *ReadWBMPImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Convert bi-level image to pixel packets. */
coders/webp.c+6 −0 modified@@ -286,6 +286,12 @@ static Image *ReadWEBPImage(const ImageInfo *image_info, (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } webp_status=WebPDecode(stream,length,&configure); } if (webp_status != VP8_STATUS_OK)
coders/wmf.c+9 −0 modified@@ -2584,6 +2584,9 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception) Image *image; + MagickBooleanType + status; + unsigned long wmf_options_flags = 0; @@ -2875,6 +2878,12 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception) "leave ReadWMFImage()"); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), " Creating canvas image with size %lux%lu",(unsigned long) image->rows,
coders/wpg.c+6 −0 modified@@ -1413,6 +1413,12 @@ static Image *ReadWPGImage(const ImageInfo *image_info, ThrowReaderException(CoderError,"DataEncodingSchemeIsNotSupported"); } } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } Finish: (void) CloseBlob(image);
coders/xbm.c+6 −0 modified@@ -291,6 +291,12 @@ static Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) CloseBlob(image); return(GetFirstImageInList(image)); } + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* Initialize hex values. */
coders/xc.c+6 −0 modified@@ -132,6 +132,12 @@ static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=1; if (image->rows == 0) image->rows=1; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); status=QueryMagickColor((char *) image_info->filename,&color,exception); if (status == MagickFalse)
coders/xcf.c+6 −0 modified@@ -1275,6 +1275,12 @@ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) XCFLayerInfo *layer_info; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } /* The read pointer. */
coders/xpm.c+6 −0 modified@@ -432,6 +432,12 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Read image pixels. */ + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } for (y=0; y < (ssize_t) image->rows; y++) { p=NextXPMLine(p);
coders/xwd.c+6 −0 modified@@ -399,6 +399,12 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception) image->columns=(size_t) ximage->width; image->rows=(size_t) ximage->height; image->depth=8; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if ((header.ncolors == 0U) || (ximage->red_mask != 0) || (ximage->green_mask != 0) || (ximage->blue_mask != 0)) image->storage_class=DirectClass;
coders/ycbcr.c+12 −0 modified@@ -149,6 +149,12 @@ static Image *ReadYCBCRImage(const ImageInfo *image_info, image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } SetImageColorspace(image,YCbCrColorspace); if (image_info->interlace != PartitionInterlace) { @@ -204,6 +210,12 @@ static Image *ReadYCBCRImage(const ImageInfo *image_info, if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } SetImageColorspace(image,YCbCrColorspace); switch (image_info->interlace) {
coders/yuv.c+12 −0 modified@@ -146,6 +146,12 @@ static Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception) image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } quantum=(size_t) (image->depth <= 8 ? 1 : 2); interlace=image_info->interlace; horizontal_factor=2; @@ -213,6 +219,12 @@ static Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; + status=SetImageExtent(image,image->columns,image->rows); + if (status == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } if (interlace == PartitionInterlace) { AppendImageFormat("Y",image->filename);
Vulnerability mechanics
Root cause
"The ReadGROUP4Image function does not check the return value of the fputc function."
Attack vector
An attacker can trigger this vulnerability by providing a crafted image file that is processed by ImageMagick. The vulnerability lies in the handling of the GROUP4 image format. When writing data to a file, the return value of `fputc` is not checked, which can lead to unexpected behavior if the write operation fails. This can be exploited to cause a denial of service.
Affected code
The vulnerability exists in the `ReadGROUP4Image` function within the `coders/tiff.c` file. Specifically, the loop that writes data using `fputc` does not check its return value.
What the fix does
The patch modifies the `ReadGROUP4Image` function in `coders/tiff.c`. It introduces a `status` variable initialized to `MagickTrue`. Inside the loop that writes data using `fputc`, a check is added to see if `fputc` returns a value different from the character written. If it does, `status` is set to `MagickFalse`. After the loop, if `status` is `MagickFalse`, the image is destroyed. This ensures that if a write operation fails, the program handles the error gracefully instead of proceeding with potentially corrupted data, thus preventing a crash.
Preconditions
- inputA crafted image file in GROUP4 format.
Generated on Jun 1, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- www.openwall.com/lists/oss-security/2016/12/26/9nvdMailing ListPatchThird Party Advisory
- bugzilla.redhat.com/show_bug.cginvdIssue TrackingPatch
- github.com/ImageMagick/ImageMagick/commit/4e914bbe371433f0590cefdf3bd5f3a5710069f9nvdIssue TrackingPatchThird Party Advisory
- github.com/ImageMagick/ImageMagick/issues/196nvdIssue TrackingPatchThird Party Advisory
- www.securityfocus.com/bid/95207nvdThird Party AdvisoryVDB Entry
News mentions
0No linked articles in our index yet.