Commit 38bc4fae2 for imagemagick.org
commit 38bc4fae2515b8694ffea53e491c87ea29877478
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sat Jan 31 12:52:41 2026 -0500
utilize a global Splay tree to guard against recursion
diff --git a/MagickCore/draw.c b/MagickCore/draw.c
index c30307ac7..62258c20f 100644
--- a/MagickCore/draw.c
+++ b/MagickCore/draw.c
@@ -1612,7 +1612,7 @@ static Image *DrawClippingMask(Image *image,const DrawInfo *draw_info,
clone_info=DestroyDrawInfo(clone_info);
separate_mask=SeparateImage(clip_mask,AlphaChannel,exception);
if (separate_mask == (Image *) NULL)
- status=MagickFalse;
+ status=MagickFalse;
else
{
clip_mask=DestroyImage(clip_mask);
@@ -3461,7 +3461,7 @@ static MagickBooleanType RenderMVGContent(Image *image,
continue;
break;
}
- if ((q == (char *) NULL) || (*q == '\0') ||
+ if ((q == (char *) NULL) || (*q == '\0') ||
(p == (char *) NULL) || ((q-4) < p))
{
status=MagickFalse;
@@ -4383,7 +4383,7 @@ static MagickBooleanType RenderMVGContent(Image *image,
case PathPrimitive:
{
coordinates=(double) TracePath(&mvg_info,token,exception);
- primitive_info=(*mvg_info.primitive_info);
+ primitive_info=(*mvg_info.primitive_info);
if (coordinates < 0.0)
{
status=MagickFalse;
@@ -5652,65 +5652,27 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
else
if (*primitive_info->text != '\0')
{
- const char
- *option;
-
- MagickBooleanType
- path_status;
-
- struct stat
- attributes;
-
/*
Read composite image.
*/
(void) CopyMagickString(clone_info->filename,primitive_info->text,
MagickPathExtent);
(void) SetImageInfo(clone_info,1,exception);
- option=GetImageOption(clone_info,"svg:embedding");
- if ((option == (char *) NULL) &&
- (IsStringTrue(option) == MagickFalse))
- {
- const MagickInfo
- *magick_info;
-
- magick_info=GetMagickInfo(clone_info->magick,exception);
- if ((magick_info != (const MagickInfo*) NULL) &&
- (LocaleCompare(magick_info->magick_module,"SVG") == 0))
- {
- (void) ThrowMagickException(exception,GetMagickModule(),
- CorruptImageError,"ImageTypeNotSupported","`%s'",
- clone_info->filename);
- clone_info=DestroyImageInfo(clone_info);
- break;
- }
- }
(void) CopyMagickString(clone_info->filename,primitive_info->text,
MagickPathExtent);
if (clone_info->size != (char *) NULL)
clone_info->size=DestroyString(clone_info->size);
if (clone_info->extract != (char *) NULL)
clone_info->extract=DestroyString(clone_info->extract);
- path_status=GetPathAttributes(clone_info->filename,&attributes);
- if (path_status != MagickFalse)
- {
- if (S_ISCHR(attributes.st_mode) == 0)
- composite_images=ReadImage(clone_info,exception);
- else
- (void) ThrowMagickException(exception,GetMagickModule(),
- FileOpenError,"UnableToOpenFile","`%s'",
- clone_info->filename);
- }
+ if ((LocaleCompare(clone_info->magick,"ftp") != 0) &&
+ (LocaleCompare(clone_info->magick,"http") != 0) &&
+ (LocaleCompare(clone_info->magick,"https") != 0) &&
+ (LocaleCompare(clone_info->magick,"mvg") != 0) &&
+ (LocaleCompare(clone_info->magick,"vid") != 0))
+ composite_images=ReadImage(clone_info,exception);
else
- if ((LocaleCompare(clone_info->magick,"ftp") != 0) &&
- (LocaleCompare(clone_info->magick,"http") != 0) &&
- (LocaleCompare(clone_info->magick,"https") != 0) &&
- (LocaleCompare(clone_info->magick,"mvg") != 0) &&
- (LocaleCompare(clone_info->magick,"vid") != 0))
- composite_images=ReadImage(clone_info,exception);
- else
- (void) ThrowMagickException(exception,GetMagickModule(),
- FileOpenError,"UnableToOpenFile","`%s'",clone_info->filename);
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ FileOpenError,"UnableToOpenFile","`%s'",clone_info->filename);
}
clone_info=DestroyImageInfo(clone_info);
if (composite_images == (Image *) NULL)
diff --git a/coders/msl.c b/coders/msl.c
index 11ff4c0e4..5f3a8779d 100644
--- a/coders/msl.c
+++ b/coders/msl.c
@@ -84,6 +84,7 @@
#include "MagickCore/segment.h"
#include "MagickCore/shear.h"
#include "MagickCore/signature.h"
+#include "MagickCore/splay-tree.h"
#include "MagickCore/statistic.h"
#include "MagickCore/static.h"
#include "MagickCore/string_.h"
@@ -141,6 +142,12 @@ typedef struct _MSLInfo
*group_info;
} MSLInfo;
+/*
+ Global declarations.
+*/
+static SplayTreeInfo
+ *msl_tree = (SplayTreeInfo *) NULL;
+
/*
Forward declarations.
*/
@@ -4774,18 +4781,20 @@ static void MSLStartElement(void *context,const xmlChar *tag,
if (value == (char *) NULL)
break;
+ if (GetValueFromSplayTree(msl_tree,value) != (const char *) NULL)
+ {
+ (void) ThrowMagickException(msl_info->exception,
+ GetMagickModule(),DrawError,
+ "VectorGraphicsNestedTooDeeply","`%s'",value);
+ break;
+ }
+ (void) AddValueToSplayTree(msl_tree,ConstantString(value),
+ (void *) 1);
*msl_info->image_info[n]->magick='\0';
(void) CopyMagickString(msl_info->image_info[n]->filename,
value,MagickPathExtent);
- (void) SetImageInfo(msl_info->image_info[n],1,exception);
- if ((LocaleCompare(msl_info->image_info[n]->magick,"msl") != 0) &&
- (LocaleCompare(msl_info->image_info[n]->magick,"svg") != 0))
- next=ReadImage(msl_info->image_info[n],exception);
- else
- (void) ThrowMagickException(msl_info->exception,
- GetMagickModule(),DrawError,
- "VectorGraphicsNestedTooDeeply","`%s'",
- msl_info->image_info[n]->filename);
+ next=ReadImage(msl_info->image_info[n],exception);
+ (void) DeleteNodeFromSplayTree(msl_tree,value);
CatchException(exception);
if (next == (Image *) NULL)
continue;
@@ -7533,6 +7542,9 @@ ModuleExport size_t RegisterMSLImage(void)
MagickInfo
*entry;
+ if (msl_tree == (SplayTreeInfo *) NULL)
+ msl_tree=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
+ (void *(*)(void *)) NULL);
entry=AcquireMagickInfo("MSL","MSL","Magick Scripting Language");
#if defined(MAGICKCORE_XML_DELEGATE)
entry->decoder=(DecodeImageHandler *) ReadMSLImage;
@@ -7853,6 +7865,8 @@ static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
ModuleExport void UnregisterMSLImage(void)
{
(void) UnregisterMagickInfo("MSL");
+ if (msl_tree != (SplayTreeInfo *) NULL)
+ msl_tree=DestroySplayTree(msl_tree);
}
#if defined(MAGICKCORE_XML_DELEGATE)
diff --git a/coders/svg.c b/coders/svg.c
index 2f8a27ebc..becb96988 100644
--- a/coders/svg.c
+++ b/coders/svg.c
@@ -185,6 +185,12 @@ typedef struct _SVGInfo
svgDepth;
} SVGInfo;
+/*
+ Global declarations.
+*/
+static SplayTreeInfo
+ *svg_tree = (SplayTreeInfo *) NULL;
+
/*
Static declarations.
*/
@@ -2653,6 +2659,26 @@ static void SVGEndElement(void *context,const xmlChar *name)
{
if (LocaleCompare((const char *) name,"image") == 0)
{
+ Image
+ *image;
+
+ ImageInfo
+ *image_info = AcquireImageInfo();
+
+ if (GetValueFromSplayTree(svg_tree,svg_info->url) != (const char *) NULL)
+ {
+ (void) ThrowMagickException(svg_info->exception,GetMagickModule(),
+ DrawError,"VectorGraphicsNestedTooDeeply","`%s'",svg_info->url);
+ break;
+ }
+ (void) AddValueToSplayTree(svg_tree,ConstantString(svg_info->url),
+ (void *) 1);
+ (void) CopyMagickString(image_info->filename,svg_info->url,
+ MagickPathExtent);
+ image=ReadImage(image_info,svg_info->exception);
+ if (image != (Image *) NULL)
+ image=DestroyImage(image);
+ (void) DeleteNodeFromSplayTree(svg_tree,svg_info->url);
(void) FormatLocaleFile(svg_info->file,
"image Over %g,%g %g,%g \"%s\"\n",svg_info->bounds.x,
svg_info->bounds.y,svg_info->bounds.width,svg_info->bounds.height,
@@ -3326,6 +3352,9 @@ ModuleExport size_t RegisterSVGImage(void)
MagickInfo
*entry;
+ if (svg_tree == (SplayTreeInfo *) NULL)
+ svg_tree=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
+ (void *(*)(void *)) NULL);
*version='\0';
#if defined(LIBXML_DOTTED_VERSION)
(void) CopyMagickString(version,"XML " LIBXML_DOTTED_VERSION,
@@ -3341,9 +3370,6 @@ ModuleExport size_t RegisterSVGImage(void)
entry=AcquireMagickInfo("SVG","SVG","Scalable Vector Graphics");
entry->decoder=(DecodeImageHandler *) ReadSVGImage;
entry->encoder=(EncodeImageHandler *) WriteSVGImage;
-#if defined(MAGICKCORE_RSVG_DELEGATE)
- entry->flags^=CoderDecoderThreadSupportFlag;
-#endif
entry->mime_type=ConstantString("image/svg+xml");
if (*version != '\0')
entry->version=ConstantString(version);
@@ -3354,9 +3380,6 @@ ModuleExport size_t RegisterSVGImage(void)
entry->decoder=(DecodeImageHandler *) ReadSVGImage;
#endif
entry->encoder=(EncodeImageHandler *) WriteSVGImage;
-#if defined(MAGICKCORE_RSVG_DELEGATE)
- entry->flags^=CoderDecoderThreadSupportFlag;
-#endif
entry->mime_type=ConstantString("image/svg+xml");
if (*version != '\0')
entry->version=ConstantString(version);
@@ -3366,7 +3389,6 @@ ModuleExport size_t RegisterSVGImage(void)
entry=AcquireMagickInfo("SVG","RSVG","Librsvg SVG renderer");
entry->decoder=(DecodeImageHandler *) ReadSVGImage;
entry->encoder=(EncodeImageHandler *) WriteSVGImage;
- entry->flags^=CoderDecoderThreadSupportFlag;
entry->mime_type=ConstantString("image/svg+xml");
if (*version != '\0')
entry->version=ConstantString(version);
@@ -3379,9 +3401,6 @@ ModuleExport size_t RegisterSVGImage(void)
entry->decoder=(DecodeImageHandler *) ReadSVGImage;
#endif
entry->encoder=(EncodeImageHandler *) WriteSVGImage;
-#if defined(MAGICKCORE_RSVG_DELEGATE)
- entry->flags^=CoderDecoderThreadSupportFlag;
-#endif
entry->magick=(IsImageFormatHandler *) IsSVG;
(void) RegisterMagickInfo(entry);
return(MagickImageCoderSignature);
@@ -3414,6 +3433,8 @@ ModuleExport void UnregisterSVGImage(void)
(void) UnregisterMagickInfo("RSVG");
#endif
(void) UnregisterMagickInfo("MSVG");
+ if (svg_tree != (SplayTreeInfo *) NULL)
+ svg_tree=DestroySplayTree(svg_tree);
}
/*