Commit 33d16f3cf for imagemagick.org
commit 33d16f3cf4e0439bba4a874e14c5a3168726ed68
Author: Cristy <urban-warrior@imagemagick.org>
Date: Mon Sep 28 22:05:26 2026 -0400
https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-8ghq-p369-g395
diff --git a/MagickCore/xml-tree.c b/MagickCore/xml-tree.c
index 3d008ffa8..9705110e1 100644
--- a/MagickCore/xml-tree.c
+++ b/MagickCore/xml-tree.c
@@ -127,6 +127,7 @@ struct _XMLTreeRoot
*semaphore;
size_t
+ depth,
signature;
};
@@ -400,9 +401,6 @@ MagickPrivate XMLTreeInfo *AddPathToXMLTree(XMLTreeInfo *xml_info,
%
*/
-static XMLTreeInfo
- *DestroyXMLTree_(XMLTreeInfo *,const size_t);
-
static char **DestroyXMLTreeAttributes(char **attributes)
{
ssize_t
@@ -427,8 +425,7 @@ static char **DestroyXMLTreeAttributes(char **attributes)
return((char **) NULL);
}
-static void DestroyXMLTreeChild(XMLTreeInfo *xml_info,
- const size_t depth)
+static void DestroyXMLTreeChild(XMLTreeInfo *xml_info)
{
XMLTreeInfo
*child,
@@ -440,12 +437,11 @@ static void DestroyXMLTreeChild(XMLTreeInfo *xml_info,
node=child;
child=node->child;
node->child=(XMLTreeInfo *) NULL;
- (void) DestroyXMLTree_(node,depth+1);
+ (void) DestroyXMLTree(node);
}
}
-static void DestroyXMLTreeOrdered(XMLTreeInfo *xml_info,
- const size_t depth)
+static void DestroyXMLTreeOrdered(XMLTreeInfo *xml_info)
{
XMLTreeInfo
*node,
@@ -457,7 +453,7 @@ static void DestroyXMLTreeOrdered(XMLTreeInfo *xml_info,
node=ordered;
ordered=node->ordered;
node->ordered=(XMLTreeInfo *) NULL;
- (void) DestroyXMLTree_(node,depth+1);
+ (void) DestroyXMLTree(node);
}
}
@@ -522,18 +518,15 @@ static void DestroyXMLTreeRoot(XMLTreeInfo *xml_info)
}
}
-static XMLTreeInfo *DestroyXMLTree_(XMLTreeInfo *xml_info,
- const size_t depth)
+MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
{
assert(xml_info != (XMLTreeInfo *) NULL);
assert((xml_info->signature == MagickCoreSignature) ||
(((XMLTreeRoot *) xml_info)->signature == MagickCoreSignature));
if (IsEventLogging() != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
- if (depth >= MagickMaxRecursionDepth)
- return((XMLTreeInfo *) NULL);
- DestroyXMLTreeChild(xml_info,depth+1);
- DestroyXMLTreeOrdered(xml_info,depth+1);
+ DestroyXMLTreeChild(xml_info);
+ DestroyXMLTreeOrdered(xml_info);
DestroyXMLTreeRoot(xml_info);
xml_info->attributes=DestroyXMLTreeAttributes(xml_info->attributes);
xml_info->content=DestroyString(xml_info->content);
@@ -541,11 +534,6 @@ static XMLTreeInfo *DestroyXMLTree_(XMLTreeInfo *xml_info,
xml_info=(XMLTreeInfo *) RelinquishMagickMemory(xml_info);
return((XMLTreeInfo *) NULL);
}
-
-MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
-{
- return(DestroyXMLTree_(xml_info,0));
-}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1236,6 +1224,7 @@ static XMLTreeInfo *ParseCloseTag(XMLTreeRoot *root,char *tag,
return(&root->root);
}
root->node=root->node->parent;
+ root->depth--;
return((XMLTreeInfo *) NULL);
}
@@ -1564,16 +1553,23 @@ static MagickBooleanType ParseInternalDoctype(XMLTreeRoot *root,char *xml,
}
for (i=0; predefined_entities[i] != (char *) NULL; i++)
if ((i & 0x01) != 0)
- predefined_entities[i]=DestroyString(predefined_entities[i]);
+ predefined_entities[i]=DestroyString(predefined_entities[i]);
predefined_entities=(char **) RelinquishMagickMemory(predefined_entities);
return(MagickTrue);
}
-static void ParseOpenTag(XMLTreeRoot *root,char *tag,char **attributes)
+static MagickBooleanType ParseOpenTag(XMLTreeRoot *root,char *tag,
+ char **attributes,ExceptionInfo *exception)
{
XMLTreeInfo
*xml_info;
+ if (root->depth >= MagickMaxRecursionDepth)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
+ "ParseError","unexpected open tag </%s>",tag);
+ return(MagickFalse);
+ }
xml_info=root->node;
if (xml_info->tag == (char *) NULL)
xml_info->tag=ConstantString(tag);
@@ -1582,6 +1578,8 @@ static void ParseOpenTag(XMLTreeRoot *root,char *tag,char **attributes)
if (xml_info != (XMLTreeInfo *) NULL)
xml_info->attributes=attributes;
root->node=xml_info;
+ root->depth++;
+ return(MagickTrue);
}
static const char
@@ -1802,7 +1800,14 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
(void) DestroyXMLTreeAttributes(attributes);
else
{
- ParseOpenTag(root,tag,attributes);
+ status=ParseOpenTag(root,tag,attributes,exception);
+ if (status == MagickFalse)
+ {
+ if (l != 0)
+ (void) DestroyXMLTreeAttributes(attributes);
+ utf8=DestroyString(utf8);
+ return(&root->root);
+ }
(void) ParseCloseTag(root,tag,exception);
}
}
@@ -1813,7 +1818,16 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
{
*p='\0';
if ((ignore_depth == 0) && (IsSkipTag(tag) == MagickFalse))
- ParseOpenTag(root,tag,attributes);
+ {
+ status=ParseOpenTag(root,tag,attributes,exception);
+ if (status == MagickFalse)
+ {
+ if (l != 0)
+ (void) DestroyXMLTreeAttributes(attributes);
+ utf8=DestroyString(utf8);
+ return(&root->root);
+ }
+ }
else
{
ignore_depth++;