diff --git a/MagickCore/memory-private.h b/MagickCore/memory-private.h index 0577a2f853..751d366d59 100644 --- a/MagickCore/memory-private.h +++ b/MagickCore/memory-private.h @@ -43,6 +43,20 @@ extern "C" { #define MagickAssumeAligned(address) (address) #endif +static inline size_t OverAllocateMemory(const size_t length) +{ + size_t + extent; + + /* + Over allocate memory, typically used when concatentating strings. + */ + extent=length; + if (extent < 131072) + for (extent=256; extent < length; extent*=2); + return(extent); +} + extern MagickPrivate void ResetMaxMemoryRequest(void), ResetVirtualAnonymousMemory(void); diff --git a/MagickCore/string.c b/MagickCore/string.c index 8e0e2e9379..dccef76a27 100644 --- a/MagickCore/string.c +++ b/MagickCore/string.c @@ -479,8 +479,8 @@ MagickExport MagickBooleanType ConcatenateString( length+=source_length; if (~length < MagickPathExtent) ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); - *destination=(char *) ResizeQuantumMemory(*destination,length+ - MagickPathExtent,sizeof(**destination)); + *destination=(char *) ResizeQuantumMemory(*destination, + OverAllocateMemory(length+MagickPathExtent),sizeof(**destination)); if (*destination == (char *) NULL) ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); if (source_length != 0) @@ -527,7 +527,19 @@ MagickExport void ConcatenateStringInfo(StringInfo *string_info, length=string_info->length; if (~length < source->length) ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); - SetStringInfoLength(string_info,length+source->length); + length+=source->length; + if (~length < MagickPathExtent) + ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); + string_info->length=length; + if (string_info->datum == (unsigned char *) NULL) + string_info->datum=(unsigned char *) AcquireQuantumMemory(length+ + MagickPathExtent,sizeof(*string_info->datum)); + else + string_info->datum=(unsigned char *) ResizeQuantumMemory( + string_info->datum,OverAllocateMemory(length+MagickPathExtent), + sizeof(*string_info->datum)); + if (string_info->datum == (unsigned char *) NULL) + ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) memcpy(string_info->datum+length,source->datum,source->length); } @@ -2611,8 +2623,8 @@ MagickExport MagickBooleanType SubstituteString(char **string, */ offset=(ssize_t) (p-(*string)); extent=strlen(*string)+replace_extent-search_extent+1; - *string=(char *) ResizeQuantumMemory(*string,extent+MagickPathExtent, - sizeof(*p)); + *string=(char *) ResizeQuantumMemory(*string, + OverAllocateMemory(extent+MagickPathExtent),sizeof(*p)); if (*string == (char *) NULL) ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); p=(*string)+offset; diff --git a/coders/gif.c b/coders/gif.c index 1301aa1df4..172fb34c8c 100644 --- a/coders/gif.c +++ b/coders/gif.c @@ -58,6 +58,7 @@ #include "MagickCore/profile.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/option.h" @@ -1102,8 +1103,9 @@ static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((ssize_t) (count+offset+MagickPathExtent) >= (ssize_t) extent) { extent<<=1; - comments=(char *) ResizeQuantumMemory(comments,extent+ - MagickPathExtent,sizeof(*comments)); + comments=(char *) ResizeQuantumMemory(comments, + OverAllocateMemory(extent+MagickPathExtent), + sizeof(*comments)); if (comments == (char *) NULL) ThrowGIFException(ResourceLimitError, "MemoryAllocationFailed"); diff --git a/coders/miff.c b/coders/miff.c index 21b91d0889..eb6b755cd9 100644 --- a/coders/miff.c +++ b/coders/miff.c @@ -577,8 +577,8 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, { *p='\0'; length<<=1; - comment=(char *) ResizeQuantumMemory(comment,length+ - MagickPathExtent,sizeof(*comment)); + comment=(char *) ResizeQuantumMemory(comment, + OverAllocateMemory(length+MagickPathExtent),sizeof(*comment)); if (comment == (char *) NULL) break; p=comment+strlen(comment);