% July 1992 %
% %
% %
-% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2017 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/configure.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
-#include "MagickCore/hashmap.h"
#include "MagickCore/image.h"
+#include "MagickCore/linked-list.h"
#include "MagickCore/memory_.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
*image;
cms_exception=(CMSExceptionInfo *) context;
- image=cms_exception->image;
+ if (cms_exception == (CMSExceptionInfo *) NULL)
+ return;
exception=cms_exception->exception;
+ if (exception == (ExceptionInfo *) NULL)
+ return;
+ image=cms_exception->image;
if (image == (Image *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),ImageWarning,
int
intent;
- MagickBooleanType
- status;
-
MagickOffsetType
progress;
}
if (target_colorspace == CMYKColorspace)
(void) SetImageColorspace(image,target_colorspace,exception);
- status=MagickTrue;
progress=0;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
target_pixels=DestroyPixelThreadSet(target_pixels);
source_pixels=DestroyPixelThreadSet(source_pixels);
transform=DestroyTransformThreadSet(transform);
- if (cmsGetDeviceClass(source_profile) != cmsSigLinkClass)
+ if ((status != MagickFalse) &&
+ (cmsGetDeviceClass(source_profile) != cmsSigLinkClass))
status=SetImageProfile(image,name,profile,exception);
if (target_profile != (cmsHPROFILE) NULL)
(void) cmsCloseProfile(target_profile);
static inline const unsigned char *ReadResourceLong(const unsigned char *p,
unsigned int *quantum)
{
- *quantum=(size_t) (*p++ << 24);
- *quantum|=(size_t) (*p++ << 16);
- *quantum|=(size_t) (*p++ << 8);
- *quantum|=(size_t) (*p++ << 0);
+ *quantum=(unsigned int) (*p++) << 24;
+ *quantum|=(unsigned int) (*p++) << 16;
+ *quantum|=(unsigned int) (*p++) << 8;
+ *quantum|=(unsigned int) (*p++);
return(p);
}
static inline const unsigned char *ReadResourceShort(const unsigned char *p,
unsigned short *quantum)
{
- *quantum=(unsigned short) (*p++ << 8);
- *quantum|=(unsigned short) (*p++ << 0);
+ *quantum=(unsigned short) (*p++) << 8;
+ *quantum|=(unsigned short) (*p++);
return(p);
-}static inline void WriteResourceLong(unsigned char *p,
+}
+
+static inline void WriteResourceLong(unsigned char *p,
const unsigned int quantum)
{
unsigned char
count=(ssize_t) value;
if ((count & 0x01) != 0)
count++;
- if ((p > (datum+length-count)) || (count > (ssize_t) length))
+ if ((count < 0) || (p > (datum+length-count)) ||
+ (count > (ssize_t) length))
break;
if (id != profile_id)
p+=count;
offset;
ssize_t
- extract_count;
+ extract_extent;
StringInfo
*extract_profile;
- extract_count=0;
+ extract_extent=0;
extent=(datum+length)-(p+count);
if (profile == (StringInfo *) NULL)
{
else
{
offset=(p-datum);
- extract_count=profile->length;
- if ((extract_count & 0x01) != 0)
- extract_count++;
- extract_profile=AcquireStringInfo(offset+extract_count+extent);
+ extract_extent=profile->length;
+ if ((extract_extent & 0x01) != 0)
+ extract_extent++;
+ extract_profile=AcquireStringInfo(offset+extract_extent+extent);
(void) CopyMagickMemory(extract_profile->datum,datum,offset-4);
- WriteResourceLong(extract_profile->datum+offset-4,
- (unsigned int)profile->length);
+ WriteResourceLong(extract_profile->datum+offset-4,(unsigned int)
+ profile->length);
(void) CopyMagickMemory(extract_profile->datum+offset,
profile->datum,profile->length);
}
- (void) CopyMagickMemory(extract_profile->datum+offset+extract_count,
+ (void) CopyMagickMemory(extract_profile->datum+offset+extract_extent,
p+count,extent);
(void) AddValueToSplayTree((SplayTreeInfo *) image->profiles,
ConstantString("8bim"),CloneStringInfo(extract_profile));
unsigned char
length_byte;
- unsigned int
- value;
+ unsigned int
+ value;
unsigned short
id;
{
if (LocaleCompare(name,"8bim") == 0)
GetProfilesFromResourceBlock(image,profile,exception);
- else if (recursive == MagickFalse)
- WriteTo8BimProfile(image,name,profile);
+ else
+ if (recursive == MagickFalse)
+ WriteTo8BimProfile(image,name,profile);
}
/*
Inject profile into image properties.
return(c);
}
-static inline unsigned short ReadProfileShort(const EndianType endian,
+static inline signed short ReadProfileShort(const EndianType endian,
unsigned char *buffer)
{
+ union
+ {
+ unsigned int
+ unsigned_value;
+
+ signed int
+ signed_value;
+ } quantum;
+
unsigned short
value;
if (endian == LSBEndian)
{
- value=(unsigned short) ((buffer[1] << 8) | buffer[0]);
- return((unsigned short) (value & 0xffff));
+ value=(unsigned short) buffer[1] << 8;
+ value|=(unsigned short) buffer[0];
+ quantum.unsigned_value=value & 0xffff;
+ return(quantum.signed_value);
}
- value=(unsigned short) ((((unsigned char *) buffer)[0] << 8) |
- ((unsigned char *) buffer)[1]);
- return((unsigned short) (value & 0xffff));
+ value=(unsigned short) buffer[0] << 8;
+ value|=(unsigned short) buffer[1];
+ quantum.unsigned_value=value & 0xffff;
+ return(quantum.signed_value);
}
-static inline unsigned int ReadProfileLong(const EndianType endian,
+static inline signed int ReadProfileLong(const EndianType endian,
unsigned char *buffer)
{
+ union
+ {
+ unsigned int
+ unsigned_value;
+
+ signed int
+ signed_value;
+ } quantum;
+
unsigned int
value;
if (endian == LSBEndian)
{
- value=(unsigned int) ((buffer[3] << 24) | (buffer[2] << 16) |
- (buffer[1] << 8 ) | (buffer[0]));
- return((unsigned int) (value & 0xffffffff));
+ value=(unsigned int) buffer[3] << 24;
+ value|=(unsigned int) buffer[2] << 16;
+ value|=(unsigned int) buffer[1] << 8;
+ value|=(unsigned int) buffer[0];
+ quantum.unsigned_value=value & 0xffffffff;
+ return(quantum.signed_value);
}
- value=(unsigned int) ((buffer[0] << 24) | (buffer[1] << 16) |
- (buffer[2] << 8) | buffer[3]);
- return((unsigned int) (value & 0xffffffff));
+ value=(unsigned int) buffer[0] << 24;
+ value|=(unsigned int) buffer[1] << 16;
+ value|=(unsigned int) buffer[2] << 8;
+ value|=(unsigned int) buffer[3];
+ quantum.unsigned_value=value & 0xffffffff;
+ return(quantum.signed_value);
}
-static inline unsigned int ReadProfileMSBLong(unsigned char **p,size_t *length)
+static inline signed int ReadProfileMSBLong(unsigned char **p,size_t *length)
{
- unsigned int
+ signed int
value;
if (*length < 4)
return(value);
}
-static inline unsigned short ReadProfileMSBShort(unsigned char **p,
+static inline signed short ReadProfileMSBShort(unsigned char **p,
size_t *length)
{
- unsigned short
+ signed short
value;
if (*length < 2)
if ((id == 0x3ED) && (count == 16))
{
if (image->units == PixelsPerCentimeterResolution)
- WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.x*2.54*
+ WriteProfileLong(MSBEndian,(unsigned int) (image->resolution.x*2.54*
65536.0),p);
else
- WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.x*
+ WriteProfileLong(MSBEndian,(unsigned int) (image->resolution.x*
65536.0),p);
WriteProfileShort(MSBEndian,(unsigned short) image->units,p+4);
if (image->units == PixelsPerCentimeterResolution)
- WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.y*2.54*
+ WriteProfileLong(MSBEndian,(unsigned int) (image->resolution.y*2.54*
65536.0),p+8);
else
- WriteProfileLong(MSBEndian, (unsigned int) (image->resolution.y*
+ WriteProfileLong(MSBEndian,(unsigned int) (image->resolution.y*
65536.0),p+8);
WriteProfileShort(MSBEndian,(unsigned short) image->units,p+12);
}
length,
number_entries;
+ SplayTreeInfo
+ *exif_resources;
+
ssize_t
id,
level,
/*
This the offset to the first IFD.
*/
- offset=(ssize_t) ((int) ReadProfileLong(endian,exif+4));
- if ((offset < 0) || (size_t) offset >= length)
+ offset=(ssize_t) ReadProfileLong(endian,exif+4);
+ if ((offset < 0) || ((size_t) offset >= length))
return(MagickFalse);
directory=exif+offset;
level=0;
entry=0;
+ exif_resources=NewSplayTree((int (*)(const void *,const void *)) NULL,
+ (void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
do
{
if (level > 0)
tag_value;
q=(unsigned char *) (directory+2+(12*entry));
+ if (q > (exif+length-12))
+ break; /* corrupt EXIF */
+ if (GetValueFromSplayTree(exif_resources,q) == q)
+ break;
+ (void) AddValueToSplayTree(exif_resources,q,q);
tag_value=(ssize_t) ReadProfileShort(endian,q);
format=(ssize_t) ReadProfileShort(endian,q+2);
- if ((format-1) >= EXIF_NUM_FORMATS)
+ if ((format < 0) || ((format-1) >= EXIF_NUM_FORMATS))
break;
- components=(ssize_t) ((int) ReadProfileLong(endian,q+4));
+ components=(int) ReadProfileLong(endian,q+4);
+ if (components < 0)
+ break; /* corrupt EXIF */
number_bytes=(size_t) components*format_bytes[format];
if ((ssize_t) number_bytes < components)
break; /* prevent overflow */
p=q+8;
else
{
- ssize_t
- offset;
-
/*
The directory entry contains an offset.
*/
- offset=(ssize_t) ((int) ReadProfileLong(endian,q+8));
- if ((size_t) (offset+number_bytes) > length)
+ offset=(ssize_t) ReadProfileLong(endian,q+8);
+ if ((offset < 0) || ((size_t) (offset+number_bytes) > length))
continue;
if (~length < number_bytes)
continue; /* prevent overflow */
}
if ((tag_value == TAG_EXIF_OFFSET) || (tag_value == TAG_INTEROP_OFFSET))
{
- ssize_t
- offset;
-
- offset=(ssize_t) ((int) ReadProfileLong(endian,p));
+ offset=(ssize_t) ReadProfileLong(endian,p);
if (((size_t) offset < length) && (level < (MaxDirectoryStack-2)))
{
directory_stack[level].directory=directory;
level++;
if ((directory+2+(12*number_entries)) > (exif+length))
break;
- offset=(ssize_t) ((int) ReadProfileLong(endian,directory+2+(12*
- number_entries)));
+ offset=(ssize_t) ReadProfileLong(endian,directory+2+(12*
+ number_entries));
if ((offset != 0) && ((size_t) offset < length) &&
(level < (MaxDirectoryStack-2)))
{
}
}
} while (level > 0);
+ exif_resources=DestroySplayTree(exif_resources);
return(MagickTrue);
}