+2018-06-06 7.0.7-39 <quetzlzacatenango@image...>
+ * Fixed numerous use of uninitialized values, integer overflow, memory
+ exceeded, and timeouts (credit to OSS Fuzz).
+
2018-06-02 7.0.7-38 Cristy <quetzlzacatenango@image...>
* Release ImageMagick version 7.0.7-38, GIT revision 14409:01e395a73:20180602.
extern MagickExport int
EOFBlob(const Image *),
+ ErrorBlob(const Image *),
ReadBlobByte(Image *);
extern MagickExport MagickBooleanType
mapped,
eof;
+ int
+ error;
+
MagickOffsetType
offset;
blob_info->size=GetBlobSize(image);
image->extent=blob_info->size;
blob_info->eof=MagickFalse;
+ blob_info->error=0;
blob_info->mode=UndefinedBlobMode;
if (blob_info->exempt != MagickFalse)
{
blob_info->length=0;
blob_info->offset=0;
blob_info->eof=MagickFalse;
+ blob_info->error=0;
blob_info->exempt=MagickFalse;
blob_info->type=UndefinedStream;
blob_info->file_info.file=(FILE *) NULL;
% %
% %
% %
++ E r r o r B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ErrorBlob() returns a non-zero value when an error has been detected reading
+% from a blob or file.
+%
+% The format of the ErrorBlob method is:
+%
+% int ErrorBlob(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+*/
+MagickExport int ErrorBlob(const Image *image)
+{
+ BlobInfo
+ *magick_restrict blob_info;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickCoreSignature);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ blob_info=image->blob;
+ switch (blob_info->type)
+ {
+ case UndefinedStream:
+ case StandardStream:
+ break;
+ case FileStream:
+ case PipeStream:
+ {
+ blob_info->error=ferror(blob_info->file_info.file);
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(MAGICKCORE_ZLIB_DELEGATE)
+ (void) gzerror(blob_info->file_info.gzfile,&blob_info->error);
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(MAGICKCORE_BZLIB_DELEGATE)
+ (void) BZ2_bzerror(blob_info->file_info.bzfile,&blob_info->error);
+#endif
+ break;
+ }
+ case FifoStream:
+ {
+ blob_info->error=0;
+ break;
+ }
+ case BlobStream:
+ break;
+ case CustomStream:
+ break;
+ }
+ return(blob_info->error);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% F i l e T o B l o b %
% %
% %
{
default:
{
- count=(ssize_t) gzread(blob_info->file_info.gzfile,q,
- (unsigned int) length);
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=(ssize_t) gzread(blob_info->file_info.gzfile,q+i,
+ (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ count=i;
break;
}
case 4:
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- count=(ssize_t) BZ2_bzread(blob_info->file_info.bzfile,q,(int) length);
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=(ssize_t) BZ2_bzread(blob_info->file_info.bzfile,q+i,
+ (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ count=i;
#endif
break;
}
register const unsigned char
*p;
+ register unsigned char
+ *q;
+
ssize_t
count;
blob_info=image->blob;
count=0;
p=(const unsigned char *) data;
+ q=(unsigned char *) data;
switch (blob_info->type)
{
case UndefinedStream:
{
default:
{
- count=(ssize_t) gzwrite(blob_info->file_info.gzfile,(void *) data,
- (unsigned int) length);
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=(ssize_t) gzwrite(blob_info->file_info.gzfile,q+i,
+ (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ count=i;
break;
}
case 4:
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- count=(ssize_t) BZ2_bzwrite(blob_info->file_info.bzfile,(void *) data,
- (int) length);
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=(ssize_t) BZ2_bzwrite(blob_info->file_info.bzfile,q+i,
+ (int) MagickMin(length-i,MagickMaxBufferExtent));
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ count=i;
#endif
break;
}
extent=(size_t) mvg_info->offset+pad+4096;
if (extent <= *mvg_info->extent)
return(MagickTrue);
- primitive_info=(*mvg_info->primitive_info);
primitive_info=AcquireQuantumMemory(extent,sizeof(*primitive_info));
if (primitive_info == (PrimitiveInfo *) NULL)
{
TracePoint(q,point);
mvg_info->offset+=q->coordinates;
q+=q->coordinates;
+ primitive_info=(*mvg_info->primitive_info)+subpath_offset;
primitive_info->coordinates=(size_t) (q-primitive_info);
primitive_info->closed_subpath=MagickTrue;
number_coordinates+=primitive_info->coordinates;
char identific[124];
unsigned short Version;
char EndianIndicator[2];
- unsigned long DataType;
+ unsigned int DataType;
unsigned int ObjectSize;
- unsigned long unknown1;
- unsigned long unknown2;
+ unsigned int unknown1;
+ unsigned int unknown2;
unsigned short unknown5;
unsigned char StructureFlag;
unsigned char StructureClass;
- unsigned long unknown3;
- unsigned long unknown4;
- unsigned long DimFlag;
+ unsigned int unknown3;
+ unsigned int unknown4;
+ unsigned int DimFlag;
- unsigned long SizeX;
- unsigned long SizeY;
+ unsigned int SizeX;
+ unsigned int SizeY;
unsigned short Flag1;
unsigned short NameFlag;
}
image->colors = GetQuantumRange(image->depth);
if (image->columns == 0 || image->rows == 0)
goto MATLAB_KO;
- if((unsigned long)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
+ if((unsigned int)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
goto MATLAB_KO;
/* Image is gray when no complex flag is set and 2D Matrix */
if ((MATLAB_HDR.DimFlag == 8) &&
StringInfo
*profile;
- const unsigned char
+ static const unsigned char
unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
goto FINISH;
/* Copy postscript to temporary file */
- (void) SeekBlob(image,PS_Offset,SEEK_SET);
+ if (SeekBlob(image,PS_Offset,SEEK_SET) != PS_Offset)
+ {
+ DestroyImageInfo(clone_info);
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ }
count=ReadBlob(image, 2*MagickPathExtent, magick);
if (count < 1)
{
ThrowReaderException(CorruptImageError,"ImproperImageHeader");
}
- (void) SeekBlob(image,PS_Offset,SEEK_SET);
+ if (SeekBlob(image,PS_Offset,SEEK_SET) != PS_Offset)
+ {
+ DestroyImageInfo(clone_info);
+ ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+ }
while (PS_Size-- > 0)
{
c=ReadBlobByte(image);
case 1: /* WPG level 1 */
while(!EOFBlob(image)) /* object parser loop */
{
- (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
+ if (SeekBlob(image,Header.DataOffset,SEEK_SET) != Header.DataOffset)
+ break;
if(EOFBlob(image))
break;
StartWPG.PosSizePrecision = 0;
while(!EOFBlob(image)) /* object parser loop */
{
- (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
- if(EOFBlob(image))
+ if (SeekBlob(image,Header.DataOffset,SEEK_SET) != Header.DataOffset)
+ break;
+ if (EOFBlob(image))
break;
Rec2.Class=(i=ReadBlobByte(image));