Commit ca9880442 for imagemagick.org

commit ca9880442eb04f148747757ceb64dfce0a7d5f74
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sun Oct 4 18:09:26 2026 +0200

    Moved shared logic to a skip a doctype or comment inside xml-tree.c

diff --git a/MagickCore/color.c b/MagickCore/color.c
index 478f59a18..69b03f88a 100644
--- a/MagickCore/color.c
+++ b/MagickCore/color.c
@@ -2028,57 +2028,7 @@ static MagickBooleanType LoadColorCache(LinkedListInfo *cache,const char *xml,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -2094,8 +2044,7 @@ static MagickBooleanType LoadColorCache(LinkedListInfo *cache,const char *xml,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/configure.c b/MagickCore/configure.c
index 3109392d8..2ac9dd29f 100644
--- a/MagickCore/configure.c
+++ b/MagickCore/configure.c
@@ -1195,57 +1195,7 @@ static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -1261,8 +1211,7 @@ static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/delegate.c b/MagickCore/delegate.c
index 6dfe8c786..1b8178fde 100644
--- a/MagickCore/delegate.c
+++ b/MagickCore/delegate.c
@@ -2145,57 +2145,7 @@ static MagickBooleanType LoadDelegateCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -2211,8 +2161,7 @@ static MagickBooleanType LoadDelegateCache(LinkedListInfo *cache,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/locale.c b/MagickCore/locale.c
index 852700e10..65a25e2c0 100644
--- a/MagickCore/locale.c
+++ b/MagickCore/locale.c
@@ -1219,57 +1219,7 @@ static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,const char *xml,
     (void) CopyMagickString(keyword,token,MagickLocaleExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -1285,12 +1235,7 @@ static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,const char *xml,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-        {
-          (void) GetNextToken(q,&q,extent,token);
-          while (isspace((int) ((unsigned char) *q)) != 0)
-            q++;
-        }
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/log.c b/MagickCore/log.c
index e1b6f33b4..c3b777834 100644
--- a/MagickCore/log.c
+++ b/MagickCore/log.c
@@ -946,57 +946,7 @@ static MagickBooleanType LoadLogCache(LinkedListInfo *cache,const char *xml,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -1012,8 +962,7 @@ static MagickBooleanType LoadLogCache(LinkedListInfo *cache,const char *xml,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/opencl.c b/MagickCore/opencl.c
index 769533a97..39ed0ea8e 100644
--- a/MagickCore/opencl.c
+++ b/MagickCore/opencl.c
@@ -88,6 +88,7 @@
 #include "MagickCore/token.h"
 #include "MagickCore/utility.h"
 #include "MagickCore/utility-private.h"
+#include "MagickCore/xml-tree-private.h"

 #if defined(MAGICKCORE_OPENCL_SUPPORT)
 #if defined(MAGICKCORE_LTDL_DELEGATE)
@@ -801,57 +802,7 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml)
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           break;
         continue;
       }
@@ -860,8 +811,7 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml)
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<device") == 0)
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index f1786e9fa..d314ace49 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -1142,57 +1142,7 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote = 0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote = 0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -1208,8 +1158,7 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/type.c b/MagickCore/type.c
index 9d09cf7a6..9fc9c5cda 100644
--- a/MagickCore/type.c
+++ b/MagickCore/type.c
@@ -64,6 +64,7 @@
 #include "MagickCore/utility.h"
 #include "MagickCore/utility-private.h"
 #include "MagickCore/xml-tree.h"
+#include "MagickCore/xml-tree-private.h"
 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
 # include "fontconfig/fontconfig.h"
 #if (FC_VERSION < 20209)
@@ -1120,57 +1121,7 @@ static MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
-        int
-          bracket_depth = 0,
-          quote=0;
-
-        /*
-          Parse DOCTYPE element.
-        */
-        for ( ; *q != '\0'; q++)
-        {
-          /*
-            Skip DTD comments.
-          */
-          if ((quote == 0) && (q[0] == '<') && (q[1] == '!') &&
-              (q[2] == '-') && (q[3] == '-'))
-            {
-              q+=4;
-              while ((*q != '\0') && !((q[0] == '-') && (q[1] == '-') &&
-                     (q[2] == '>')))
-                q++;
-              if (*q == '\0')
-                break;
-              q+=2;
-              continue;
-            }
-          if (quote != 0)
-            {
-              if (*q == quote)
-                quote=0;
-            }
-          else
-            {
-              if ((*q == '"') || (*q == '\''))
-                quote = (*q);
-              else
-                if (*q == '[')
-                  bracket_depth++;
-                else
-                  if (*q == ']')
-                    {
-                      if (bracket_depth > 0)
-                        bracket_depth--;
-                    }
-                  else
-                    if ((*q == '>') && (bracket_depth == 0))
-                      {
-                        q++;
-                        break;
-                      }
-            }
-        }
-        if (*q == '\0')
+        if (SkipXMLDocType(&q) == MagickFalse)
           {
             /*
               Detect unterminated DOCTYPE.
@@ -1186,8 +1137,7 @@ static MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
         /*
           Comment element.
         */
-        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
+        SkipXMLComment(&q);
         continue;
       }
     if (LocaleCompare(keyword,"<include") == 0)
diff --git a/MagickCore/xml-tree-private.h b/MagickCore/xml-tree-private.h
index 5948b4552..c8d4843a1 100644
--- a/MagickCore/xml-tree-private.h
+++ b/MagickCore/xml-tree-private.h
@@ -120,6 +120,12 @@ static inline char *SubstituteXMLEntities(const char *content,
 extern MagickPrivate char
   *FileToXML(const char *,const size_t);

+extern MagickPrivate MagickBooleanType
+  SkipXMLDocType(const char **);
+
+extern MagickPrivate void
+  SkipXMLComment(const char **);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/MagickCore/xml-tree.c b/MagickCore/xml-tree.c
index 91bcf4a1a..9b01ff6e8 100644
--- a/MagickCore/xml-tree.c
+++ b/MagickCore/xml-tree.c
@@ -2105,6 +2105,103 @@ MagickExport XMLTreeInfo *SetXMLTreeContent(XMLTreeInfo *xml_info,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   S k i p X M L C o m m e n t                                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  SkipXMLComment() advances past an XML comment.
+%
+*/
+MagickPrivate void SkipXMLComment(const char **xml)
+{
+  const char
+    *p;
+
+  for (p=*xml; *p != '\0'; p++)
+    if ((p[0] == '-') && (p[1] == '-') && (p[2] == '>'))
+      {
+        *xml=p+3;
+        return;
+      }
+  *xml=p;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   S k i p X M L D O C T Y P E                                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  SkipXMLDocType() skips a DOCTYPE declaration, including its internal subset.
+%
+*/
+MagickPrivate MagickBooleanType SkipXMLDocType(const char **xml)
+{
+  const char
+    *p;
+
+  int
+    bracket_depth,
+    quote;
+
+  bracket_depth=0;
+  quote=0;
+  for (p=*xml; *p != '\0'; p++)
+  {
+    if ((quote == 0) && (p[0] == '<') && (p[1] == '!') &&
+        (p[2] == '-') && (p[3] == '-'))
+      {
+        p+=4;
+        while ((*p != '\0') && !((p[0] == '-') && (p[1] == '-') &&
+               (p[2] == '>')))
+          p++;
+        if (*p == '\0')
+          break;
+        p+=2;
+        continue;
+      }
+    if (quote != 0)
+      {
+        if (*p == quote)
+          quote=0;
+      }
+    else
+      {
+        if ((*p == '"') || (*p == '\''))
+          quote=(*p);
+        else
+          if (*p == '[')
+            bracket_depth++;
+          else
+            if (*p == ']')
+              {
+                if (bracket_depth > 0)
+                  bracket_depth--;
+              }
+            else
+              if ((*p == '>') && (bracket_depth == 0))
+                {
+                  *xml=p+1;
+                  return(MagickTrue);
+                }
+      }
+  }
+  *xml=p;
+  return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   X M L T r e e I n f o T o X M L                                           %
 %                                                                             %
 %                                                                             %