# HG changeset patch # User Bob Friesenhahn # Date 1500755954 18000 # Node ID d00b74315a716a62386de06732afdd2822b9f1fd # Parent 4089bde04d744cbe15842284568b2ed086dd3832 CMYK: Fixed heap overflow with multiple frames with varying widths. diff -r 4089bde04d74 -r d00b74315a71 coders/cmyk.c --- a/coders/cmyk.c Sat Jul 22 13:08:14 2017 -0500 +++ b/coders/cmyk.c Sat Jul 22 15:39:14 2017 -0500 @@ -1,5 +1,5 @@ /* -% Copyright (C) 2003 - 2015 GraphicsMagick Group +% Copyright (C) 2003 - 2017 GraphicsMagick Group % Copyright (C) 2002 ImageMagick Studio % Copyright 1991-1999 E. I. du Pont de Nemours and Company % @@ -92,8 +92,8 @@ y; register long - i, - x; + x, + i; register PixelPacket *q; @@ -608,16 +608,17 @@ */ static unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image) { - int + long y; register const PixelPacket *p; unsigned char - *pixels; + *pixels = (unsigned char *) NULL; unsigned int + depth, packet_size, quantum_size, scene, @@ -629,27 +630,11 @@ ExportPixelAreaInfo export_info; - if (image->depth <= 8) - quantum_size=8; - else if (image->depth <= 16) - quantum_size=16; - else - quantum_size=32; - - - /* - Allocate memory for pixels. - */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); - packet_size=(quantum_size*4)/8; - if (LocaleCompare(image_info->magick,"CMYKA") == 0) - packet_size=(quantum_size*5)/8; - pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns); - if (pixels == (unsigned char *) NULL) - ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); + if (image_info->interlace != PartitionInterlace) { /* @@ -659,16 +644,39 @@ if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } + + /* + Support depth in multiples of 8 bits. + */ + if (image->depth > 16) + depth=32; + else if (image->depth > 8) + depth=16; + else + depth=8; + + if (depth <= 8) + quantum_size=8; + else if (depth <= 16) + quantum_size=16; + else + quantum_size=32; + + packet_size=(quantum_size*4)/8; + if (LocaleCompare(image_info->magick,"CMYKA") == 0) + packet_size=(quantum_size*5)/8; + scene=0; do { /* - Convert MIFF to CMYK raster pixels. + Allocate memory for pixels. */ - (void) TransformColorspace(image,CMYKColorspace); - if (LocaleCompare(image_info->magick,"CMYKA") == 0) - if (!image->matte) - SetImageOpacity(image,OpaqueOpacity); + MagickReallocMemory(unsigned char *,pixels, + MagickArraySize(packet_size,image->columns)); + if (pixels == (unsigned char *) NULL) + ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); + /* Initialize export options. */ @@ -677,10 +685,28 @@ export_options.endian=image->endian; else if (image_info->endian != UndefinedEndian) export_options.endian=image_info->endian; - if (image->logging) - (void) LogMagickEvent(CoderEvent,GetMagickModule(), - "Image depth %u bits, Endian %s",quantum_size, - EndianTypeToString(export_options.endian)); + + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "%lu: " + "Geometry %lux%lu, " + "Depth %u bits, " + "Endian %s, Packet Size %u, " + "Row bytes %" MAGICK_SIZE_T_F "u", + image->scene, + image->columns,image->rows, + quantum_size, + EndianTypeToString(export_options.endian), + packet_size, + (MAGICK_SIZE_T) MagickArraySize(packet_size,image->columns)); + + /* + Convert MIFF to CMYK raster pixels. + */ + (void) TransformColorspace(image,CMYKColorspace); + if (LocaleCompare(image_info->magick,"CMYKA") == 0) + if (!image->matte) + SetImageOpacity(image,OpaqueOpacity); + switch (image_info->interlace) { case NoInterlace: @@ -689,23 +715,17 @@ /* No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK... */ + const QuantumType quantum_type = + (LocaleCompare(image_info->magick,"CMYKA") == 0) ? CMYKAQuantum : + CMYKQuantum; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; - if (LocaleCompare(image_info->magick,"CMYKA") != 0) - { - (void) ExportImagePixelArea(image,CMYKQuantum,quantum_size,pixels, - &export_options,&export_info); - (void) WriteBlob(image,export_info.bytes_exported,pixels); - } - else - { - (void) ExportImagePixelArea(image,CMYKAQuantum,quantum_size,pixels, - &export_options,&export_info); - (void) WriteBlob(image,export_info.bytes_exported,pixels); - } + (void) ExportImagePixelArea(image,quantum_type,quantum_size,pixels, + &export_options,&export_info); + (void) WriteBlob(image,export_info.bytes_exported,pixels); if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception,