From: dirk Date: Thu, 16 Apr 2015 21:05:08 +0000 (+0000) Subject: Reduce stack requirements for SetImageInfo. X-Git-Tag: 7.0.1-0~1091 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f6816192b5724ef97553a83c73843009e0d70a6;p=imagemagick Reduce stack requirements for SetImageInfo. --- diff --git a/MagickCore/image.c b/MagickCore/image.c index 3e21b9273..36750dda8 100644 --- a/MagickCore/image.c +++ b/MagickCore/image.c @@ -2349,11 +2349,9 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, const unsigned int frames,ExceptionInfo *exception) { char - extension[MagickPathExtent], - filename[MagickPathExtent], + component[MagickPathExtent], magic[MagickPathExtent], - *q, - subimage[MagickPathExtent]; + *q; const MagicInfo *magic_info; @@ -2376,9 +2374,6 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, ssize_t count; - unsigned char - magick[2*MagickPathExtent]; - /* Look for 'image.format' in filename. */ @@ -2387,17 +2382,17 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); - *subimage='\0'; - GetPathComponent(image_info->filename,SubimagePath,subimage); - if (*subimage != '\0') + *component='\0'; + GetPathComponent(image_info->filename,SubimagePath,component); + if (*component != '\0') { /* Look for scene specification (e.g. img0001.pcd[4]). */ - if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse) + if (IsSceneGeometry(component,MagickFalse) == MagickFalse) { - if (IsGeometry(subimage) != MagickFalse) - (void) CloneString(&image_info->extract,subimage); + if (IsGeometry(component) != MagickFalse) + (void) CloneString(&image_info->extract,component); } else { @@ -2405,7 +2400,7 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, first, last; - (void) CloneString(&image_info->scenes,subimage); + (void) CloneString(&image_info->scenes,component); image_info->scene=StringToUnsignedLong(image_info->scenes); image_info->number_scenes=image_info->scene; p=image_info->scenes; @@ -2430,39 +2425,39 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, image_info->number_scenes-=image_info->scene-1; } } - *extension='\0'; + *component='\0'; if (*image_info->magick == '\0') - GetPathComponent(image_info->filename,ExtensionPath,extension); + GetPathComponent(image_info->filename,ExtensionPath,component); #if defined(MAGICKCORE_ZLIB_DELEGATE) - if (*extension != '\0') - if ((LocaleCompare(extension,"gz") == 0) || - (LocaleCompare(extension,"Z") == 0) || - (LocaleCompare(extension,"svgz") == 0) || - (LocaleCompare(extension,"wmz") == 0)) + if (*component != '\0') + if ((LocaleCompare(component,"gz") == 0) || + (LocaleCompare(component,"Z") == 0) || + (LocaleCompare(component,"svgz") == 0) || + (LocaleCompare(component,"wmz") == 0)) { char path[MagickPathExtent]; (void) CopyMagickString(path,image_info->filename,MagickPathExtent); - path[strlen(path)-strlen(extension)-1]='\0'; - GetPathComponent(path,ExtensionPath,extension); + path[strlen(path)-strlen(component)-1]='\0'; + GetPathComponent(path,ExtensionPath,component); } #endif #if defined(MAGICKCORE_BZLIB_DELEGATE) - if (*extension != '\0') - if (LocaleCompare(extension,"bz2") == 0) + if (*component != '\0') + if (LocaleCompare(component,"bz2") == 0) { char path[MagickPathExtent]; (void) CopyMagickString(path,image_info->filename,MagickPathExtent); - path[strlen(path)-strlen(extension)-1]='\0'; - GetPathComponent(path,ExtensionPath,extension); + path[strlen(path)-strlen(component)-1]='\0'; + GetPathComponent(path,ExtensionPath,component); } #endif image_info->affirm=MagickFalse; sans_exception=AcquireExceptionInfo(); - if (*extension != '\0') + if (*component != '\0') { MagickFormatType format_type; @@ -2496,7 +2491,7 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, /* User specified image format. */ - (void) CopyMagickString(magic,extension,MagickPathExtent); + (void) CopyMagickString(magic,component,MagickPathExtent); LocaleUpper(magic); /* Look for explicit image formats. @@ -2553,17 +2548,17 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, if ((magick_info == (const MagickInfo *) NULL) || (GetMagickEndianSupport(magick_info) == MagickFalse)) image_info->endian=UndefinedEndian; - GetPathComponent(image_info->filename,CanonicalPath,filename); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); + GetPathComponent(image_info->filename,CanonicalPath,component); + (void) CopyMagickString(image_info->filename,component,MagickPathExtent); if ((image_info->adjoin != MagickFalse) && (frames > 1)) { /* Test for multiple image support (e.g. image%02d.png). */ (void) InterpretImageFilename(image_info,(Image *) NULL, - image_info->filename,(int) image_info->scene,filename,exception); - if ((LocaleCompare(filename,image_info->filename) != 0) && - (strchr(filename,'%') == (char *) NULL)) + image_info->filename,(int) image_info->scene,component,exception); + if ((LocaleCompare(component,image_info->filename) != 0) && + (strchr(component,'%') == (char *) NULL)) image_info->adjoin=MagickFalse; } if ((image_info->adjoin != MagickFalse) && (frames > 0)) @@ -2580,9 +2575,18 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, return(MagickTrue); if (frames == 0) { + unsigned char + *magick; + + size_t + magick_size; + /* Determine the image format from the first few bytes of the file. */ + magick_size=GetMagicInfoBufferSize(exception); + if (magick_size == 0) + return(MagickFalse); image=AcquireImage(image_info,exception); (void) CopyMagickString(image->filename,image_info->filename, MagickPathExtent); @@ -2598,8 +2602,8 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, /* Copy standard input or pipe to temporary file. */ - *filename='\0'; - status=ImageToFile(image,filename,exception); + *component='\0'; + status=ImageToFile(image,component,exception); (void) CloseBlob(image); if (status == MagickFalse) { @@ -2607,18 +2611,25 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, return(MagickFalse); } SetImageInfoFile(image_info,(FILE *) NULL); - (void) CopyMagickString(image->filename,filename,MagickPathExtent); + (void) CopyMagickString(image->filename,component,MagickPathExtent); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImage(image); return(MagickFalse); } - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); + (void) CopyMagickString(image_info->filename,component,MagickPathExtent); image_info->temporary=MagickTrue; } - (void) ResetMagickMemory(magick,0,sizeof(magick)); - count=ReadBlob(image,2*MagickPathExtent,magick); + magick=(unsigned char *) AcquireMagickMemory(magick_size); + if (magick == (unsigned char *) NULL) + { + (void) CloseBlob(image); + image=DestroyImage(image); + return(MagickFalse); + } + (void) ResetMagickMemory(magick,0,magick_size); + count=ReadBlob(image,magick_size,magick); (void) SeekBlob(image,-((MagickOffsetType) count),SEEK_CUR); (void) CloseBlob(image); image=DestroyImage(image); @@ -2627,6 +2638,7 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, */ sans_exception=AcquireExceptionInfo(); magic_info=GetMagicInfo(magick,(size_t) count,sans_exception); + magick=(unsigned char *) RelinquishMagickMemory(magick); if ((magic_info != (const MagicInfo *) NULL) && (GetMagicName(magic_info) != (char *) NULL)) { diff --git a/MagickCore/magic.c b/MagickCore/magic.c index 848262296..c4887560f 100644 --- a/MagickCore/magic.c +++ b/MagickCore/magic.c @@ -243,6 +243,17 @@ static MagickBooleanType % o exception: return any errors or warnings in this structure. % */ +static int CompareMagickInfoSize(const void *a,const void *b) +{ + MagicInfo + *ma, + *mb; + + ma=(MagicInfo *)a; + mb=(MagicInfo *)b; + return((mb->offset+mb->length) - (ma->offset+ma->length)); +} + static LinkedListInfo *AcquireMagicCache(const char *filename, ExceptionInfo *exception) { @@ -308,7 +319,8 @@ static LinkedListInfo *AcquireMagicCache(const char *filename, magic_info->length=p->length; magic_info->exempt=MagickTrue; magic_info->signature=MagickSignature; - status&=AppendValueToLinkedList(magic_cache,magic_info); + status&=InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoSize, + NULL,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name); @@ -321,7 +333,7 @@ static LinkedListInfo *AcquireMagicCache(const char *filename, % % % % % % -+ G e t M a g i c I n f o % +% G e t M a g i c I n f o % % % % % % % @@ -379,6 +391,52 @@ MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic, UnlockSemaphoreInfo(magic_semaphore); return(p); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% G e t M a g i c I n f o B u f f e r S i z e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% GetMagicInfoBufferSize() searches the the size of the buffer that is +% necessary to check all the MagickInfos. Returns zero if the list is empty. +% +% The format of the GetMagicInfoBufferSize method is: +% +% size_t GetMagicInfoBufferSize(ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport size_t GetMagicInfoBufferSize(ExceptionInfo *exception) +{ + register const MagicInfo + *p; + + static size_t + size=0; + + assert(exception != (ExceptionInfo *) NULL); + if (size != 0 || IsMagicCacheInstantiated(exception) == MagickFalse) + return(size); + /* + The list is sorted so we can use the size of the first value. + */ + LockSemaphoreInfo(magic_semaphore); + ResetLinkedListIterator(magic_cache); + p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache); + if (p != (const MagicInfo *) NULL) + size=(size_t) (p->offset+p->length); + UnlockSemaphoreInfo(magic_semaphore); + return(size); +} /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -868,7 +926,8 @@ static MagickBooleanType LoadMagicCache(LinkedListInfo *magic_cache, continue; if (LocaleCompare(keyword,"/>") == 0) { - status=AppendValueToLinkedList(magic_cache,magic_info); + status=InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoSize, + NULL,magic_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", diff --git a/MagickCore/magic.h b/MagickCore/magic.h index e3d3c2f7c..2d5137c47 100644 --- a/MagickCore/magic.h +++ b/MagickCore/magic.h @@ -59,6 +59,9 @@ extern MagickExport const MagicInfo *GetMagicInfo(const unsigned char *,const size_t,ExceptionInfo *), **GetMagicInfoList(const char *,size_t *,ExceptionInfo *); +extern MagickExport size_t + GetMagicInfoBufferSize(ExceptionInfo *); + #if defined(__cplusplus) || defined(c_plusplus) } #endif