Commit 399d4bd3b for imagemagick.org

commit 399d4bd3b081f44c7fef78153f65e8cdebed9f1a
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Sun Sep 6 22:40:38 2026 -0400

    more robuse DOCTYPE parser

diff --git a/MagickCore/color.c b/MagickCore/color.c
index 651695012..b38b4527f 100644
--- a/MagickCore/color.c
+++ b/MagickCore/color.c
@@ -2028,12 +2028,41 @@ 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;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/configure.c b/MagickCore/configure.c
index 6fafa67ca..63aec4e32 100644
--- a/MagickCore/configure.c
+++ b/MagickCore/configure.c
@@ -1195,12 +1195,41 @@ static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
+        int
+          bracket_depth = 0,
+          quote = 0;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/delegate.c b/MagickCore/delegate.c
index ffa5a9c7e..9c6e76a2f 100644
--- a/MagickCore/delegate.c
+++ b/MagickCore/delegate.c
@@ -2104,12 +2104,41 @@ static MagickBooleanType LoadDelegateCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
+        int
+          bracket_depth = 0,
+          quote = 0;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/locale.c b/MagickCore/locale.c
index f695af150..52c9c8f15 100644
--- a/MagickCore/locale.c
+++ b/MagickCore/locale.c
@@ -1219,12 +1219,41 @@ 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;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/log.c b/MagickCore/log.c
index 9aaac861b..2912b5e2f 100644
--- a/MagickCore/log.c
+++ b/MagickCore/log.c
@@ -946,12 +946,41 @@ 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;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/opencl.c b/MagickCore/opencl.c
index d7ab1ad84..aaec80cc3 100644
--- a/MagickCore/opencl.c
+++ b/MagickCore/opencl.c
@@ -801,12 +801,41 @@ 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;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index da4f3813a..7c95da46f 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -1144,12 +1144,41 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
     (void) CopyMagickString(keyword,token,MagickPathExtent);
     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
       {
+        int
+          bracket_depth = 0,
+          quote = 0;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {
diff --git a/MagickCore/type.c b/MagickCore/type.c
index 57a281aea..7f426811c 100644
--- a/MagickCore/type.c
+++ b/MagickCore/type.c
@@ -1120,12 +1120,41 @@ 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;
+
         /*
-          Doctype element.
+          DOCTYPE element.
         */
-        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
-          (void) GetNextToken(q,&q,extent,token);
-        continue;
+        for ( ; *q != '\0'; q++)
+        {
+          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++;   /* consume final '>' */
+                        break;
+                      }
+            }
+        }
       }
     if (LocaleNCompare(keyword,"<!--",4) == 0)
       {