% July 1992 %
% %
% %
-% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
% obtain a copy of the License at %
% %
-% http://www.imagemagick.org/script/license.php %
+% https://www.imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
#include "MagickCore/list.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
+#include "MagickCore/memory-private.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/pixel-accessor.h"
static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define ThrowPCXException(severity,tag) \
- { \
+{ \
+ if (scanline != (unsigned char *) NULL) \
scanline=(unsigned char *) RelinquishMagickMemory(scanline); \
+ if (pixel_info != (MemoryInfo *) NULL) \
pixel_info=RelinquishVirtualMemory(pixel_info); \
- ThrowReaderException(severity,tag); \
- }
+ if (page_table != (MagickOffsetType *) NULL) \
+ page_table=(MagickOffsetType *) RelinquishMagickMemory(page_table); \
+ ThrowReaderException(severity,tag); \
+}
Image
*image;
Open image file.
*/
assert(image_info != (const ImageInfo *) NULL);
- assert(image_info->signature == MagickSignature);
+ assert(image_info->signature == MagickCoreSignature);
if (image_info->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
image_info->filename);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
Determine if this a PCX file.
*/
page_table=(MagickOffsetType *) NULL;
+ scanline=(unsigned char *) NULL;
+ pixel_info=(MemoryInfo *) NULL;
if (LocaleCompare(image_info->magick,"DCX") == 0)
{
size_t
*/
magic=ReadBlobLSBLong(image);
if (magic != 987654321)
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
page_table=(MagickOffsetType *) AcquireQuantumMemory(1024UL,
sizeof(*page_table));
if (page_table == (MagickOffsetType *) NULL)
- ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ ThrowPCXException(ResourceLimitError,"MemoryAllocationFailed");
for (id=0; id < 1024; id++)
{
page_table[id]=(MagickOffsetType) ReadBlobLSBLong(image);
{
offset=SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET);
if (offset < 0)
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
}
count=ReadBlob(image,1,&pcx_info.identifier);
for (id=1; id < 1024; id++)
*/
pcx_info.version=(unsigned char) ReadBlobByte(image);
if ((count != 1) || (pcx_info.identifier != 0x0a))
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
pcx_info.encoding=(unsigned char) ReadBlobByte(image);
bits_per_pixel=ReadBlobByte(image);
if (bits_per_pixel == -1)
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
pcx_info.bits_per_pixel=(unsigned char) bits_per_pixel;
pcx_info.left=ReadBlobLSBShort(image);
pcx_info.top=ReadBlobLSBShort(image);
image->rows=(size_t) MagickAbsoluteValue((ssize_t) pcx_info.bottom-
pcx_info.top)+1UL;
if ((image->columns == 0) || (image->rows == 0) ||
- ((pcx_info.bits_per_pixel != 1) &&
- (pcx_info.bits_per_pixel != 2) &&
- (pcx_info.bits_per_pixel != 4) &&
- (pcx_info.bits_per_pixel != 8)))
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ((pcx_info.bits_per_pixel != 1) && (pcx_info.bits_per_pixel != 2) &&
+ (pcx_info.bits_per_pixel != 4) && (pcx_info.bits_per_pixel != 8)))
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
image->depth=pcx_info.bits_per_pixel;
image->units=PixelsPerInchResolution;
image->resolution.x=(double) pcx_info.horizontal_resolution;
image->resolution.y=(double) pcx_info.vertical_resolution;
image->colors=16;
+ 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,exception);
+ if (status == MagickFalse)
+ ThrowPCXException(exception->severity,exception->reason);
+ (void) SetImageBackgroundColor(image,exception);
+ (void) memset(pcx_colormap,0,sizeof(pcx_colormap));
count=ReadBlob(image,3*image->colors,pcx_colormap);
if (count != (ssize_t) (3*image->colors))
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
pcx_info.reserved=(unsigned char) ReadBlobByte(image);
pcx_info.planes=(unsigned char) ReadBlobByte(image);
+ if (pcx_info.planes == 0)
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
+ if (pcx_info.planes > 6)
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
if ((pcx_info.bits_per_pixel*pcx_info.planes) >= 64)
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
one=1;
if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1))
if ((pcx_info.version == 3) || (pcx_info.version == 5) ||
image->colors=(size_t) MagickMin(one << (1UL*
(pcx_info.bits_per_pixel*pcx_info.planes)),256UL);
if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
- ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ ThrowPCXException(ResourceLimitError,"MemoryAllocationFailed");
if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1))
image->storage_class=DirectClass;
p=pcx_colormap;
pcx_info.vertical_screensize=ReadBlobLSBShort(image);
for (i=0; i < 54; i++)
(void) ReadBlobByte(image);
- 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,exception);
- if (status == MagickFalse)
- return(DestroyImageList(image));
/*
Read image data.
*/
- pcx_packets=(size_t) image->rows*pcx_info.bytes_per_line*pcx_info.planes;
+ if (HeapOverflowSanityCheck(image->rows, (size_t) pcx_info.bytes_per_line) != MagickFalse)
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
+ pcx_packets=(size_t) image->rows*pcx_info.bytes_per_line;
+ if (HeapOverflowSanityCheck(pcx_packets, (size_t) pcx_info.planes) != MagickFalse)
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
+ pcx_packets=(size_t) pcx_packets*pcx_info.planes;
if ((size_t) (pcx_info.bits_per_pixel*pcx_info.planes*image->columns) >
(pcx_packets*8U))
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
scanline=(unsigned char *) AcquireQuantumMemory(MagickMax(image->columns,
pcx_info.bytes_per_line),MagickMax(8,pcx_info.planes)*sizeof(*scanline));
pixel_info=AcquireVirtualMemory(pcx_packets,2*sizeof(*pixels));
scanline=(unsigned char *) RelinquishMagickMemory(scanline);
if (pixel_info != (MemoryInfo *) NULL)
pixel_info=RelinquishVirtualMemory(pixel_info);
- ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ ThrowPCXException(ResourceLimitError,"MemoryAllocationFailed");
}
+ (void) memset(scanline,0,(size_t) MagickMax(image->columns,
+ pcx_info.bytes_per_line)*MagickMax(8,pcx_info.planes)*sizeof(*scanline));
pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
+ (void) memset(pixels,0,(size_t) pcx_packets*(2*sizeof(*pixels)));
/*
Uncompress image data.
*/
break;
offset=SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET);
if (offset < 0)
- ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ ThrowPCXException(CorruptImageError,"ImproperImageHeader");
count=ReadBlob(image,1,&pcx_info.identifier);
if ((count != 0) && (pcx_info.identifier == 0x0a))
{
MagickInfo
*entry;
- entry=SetMagickInfo("DCX");
+ entry=AcquireMagickInfo("PCX","DCX","ZSoft IBM PC multi-page Paintbrush");
entry->decoder=(DecodeImageHandler *) ReadPCXImage;
entry->encoder=(EncodeImageHandler *) WritePCXImage;
- entry->flags|=CoderSeekableStreamFlag;
+ entry->flags|=CoderDecoderSeekableStreamFlag;
+ entry->flags|=CoderEncoderSeekableStreamFlag;
entry->magick=(IsImageFormatHandler *) IsDCX;
- entry->description=ConstantString("ZSoft IBM PC multi-page Paintbrush");
- entry->module=ConstantString("PCX");
(void) RegisterMagickInfo(entry);
- entry=SetMagickInfo("PCX");
+ entry=AcquireMagickInfo("PCX","PCX","ZSoft IBM PC Paintbrush");
entry->decoder=(DecodeImageHandler *) ReadPCXImage;
entry->encoder=(EncodeImageHandler *) WritePCXImage;
entry->magick=(IsImageFormatHandler *) IsPCX;
entry->flags^=CoderAdjoinFlag;
- entry->flags|=CoderSeekableStreamFlag;
- entry->description=ConstantString("ZSoft IBM PC Paintbrush");
- entry->module=ConstantString("PCX");
+ entry->flags|=CoderDecoderSeekableStreamFlag;
+ entry->flags|=CoderEncoderSeekableStreamFlag;
(void) RegisterMagickInfo(entry);
return(MagickImageCoderSignature);
}
Open output image file.
*/
assert(image_info != (const ImageInfo *) NULL);
- assert(image_info->signature == MagickSignature);
+ assert(image_info->signature == MagickCoreSignature);
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
+ if ((image->columns > 65535UL) || (image->rows > 65535UL))
+ ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
(void) TransformImageColorspace(image,sRGBColorspace,exception);
page_table=(MagickOffsetType *) NULL;
if ((LocaleCompare(image_info->magick,"DCX") == 0) ||
if (image->alpha_trait != UndefinedPixelTrait)
pcx_info.planes++;
}
- pcx_info.bytes_per_line=(unsigned short) (((size_t) image->columns*
- pcx_info.bits_per_pixel+7)/8);
+ length=(((size_t) image->columns*pcx_info.bits_per_pixel+7)/8);
+ if (length > 65535UL)
+ ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
+ pcx_info.bytes_per_line=(unsigned short) length;
pcx_info.palette_info=1;
pcx_info.colormap_signature=0x0c;
/*
length=(size_t) pcx_info.bytes_per_line;
pixel_info=AcquireVirtualMemory(length,pcx_info.planes*sizeof(*pixels));
if (pixel_info == (MemoryInfo *) NULL)
- ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+ {
+ pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap);
+ if (page_table != (MagickOffsetType *) NULL)
+ page_table=(MagickOffsetType *) RelinquishMagickMemory(page_table);
+ ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+ }
pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
q=pixels;
if ((image->storage_class == DirectClass) || (image->colors > 256))
break;
if (image->previous == (Image *) NULL)
{
- status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
- image->rows);
+ status=SetImageProgress(image,SaveImageTag,(MagickOffsetType)
+ y,image->rows);
if (status == MagickFalse)
break;
}
page_table[scene+1]=0;
offset=SeekBlob(image,0L,SEEK_SET);
if (offset < 0)
- ThrowWriterException(CorruptImageError,"ImproperImageHeader");
+ {
+ page_table=(MagickOffsetType *) RelinquishMagickMemory(page_table);
+ ThrowWriterException(CorruptImageError,"ImproperImageHeader");
+ }
(void) WriteBlobLSBLong(image,0x3ADE68B1L);
for (i=0; i <= (ssize_t) scene; i++)
(void) WriteBlobLSBLong(image,(unsigned int) page_table[i]);