Commit a75aab273 for imagemagick.org
commit a75aab27367c4a0e57e137eb6cc5369001c85aec
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sat Oct 3 13:53:54 2026 -0400
https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-4wfv-467j-fqh9
diff --git a/MagickCore/color.c b/MagickCore/color.c
index affac046a..e43f88d3f 100644
--- a/MagickCore/color.c
+++ b/MagickCore/color.c
@@ -2031,21 +2031,36 @@ static MagickBooleanType LoadColorCache(LinkedListInfo *cache,const char *xml,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -2058,11 +2073,20 @@ static MagickBooleanType LoadColorCache(LinkedListInfo *cache,const char *xml,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/configure.c b/MagickCore/configure.c
index 5d7660e70..90308092e 100644
--- a/MagickCore/configure.c
+++ b/MagickCore/configure.c
@@ -1198,21 +1198,36 @@ static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -1225,11 +1240,20 @@ static MagickBooleanType LoadConfigureCache(LinkedListInfo *cache,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/delegate.c b/MagickCore/delegate.c
index d8b59cc46..9bdc5c7a7 100644
--- a/MagickCore/delegate.c
+++ b/MagickCore/delegate.c
@@ -2148,21 +2148,36 @@ static MagickBooleanType LoadDelegateCache(LinkedListInfo *cache,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -2175,11 +2190,20 @@ static MagickBooleanType LoadDelegateCache(LinkedListInfo *cache,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/locale.c b/MagickCore/locale.c
index e94340e67..262d0134c 100644
--- a/MagickCore/locale.c
+++ b/MagickCore/locale.c
@@ -1222,21 +1222,36 @@ static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,const char *xml,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -1249,11 +1264,20 @@ static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,const char *xml,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/log.c b/MagickCore/log.c
index f9377e1f8..44392cc7c 100644
--- a/MagickCore/log.c
+++ b/MagickCore/log.c
@@ -949,21 +949,36 @@ static MagickBooleanType LoadLogCache(LinkedListInfo *cache,const char *xml,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -976,11 +991,20 @@ static MagickBooleanType LoadLogCache(LinkedListInfo *cache,const char *xml,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/opencl.c b/MagickCore/opencl.c
index f1bd70ba9..ba353178d 100644
--- a/MagickCore/opencl.c
+++ b/MagickCore/opencl.c
@@ -804,21 +804,36 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml)
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -831,11 +846,20 @@ static void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml)
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index 85d66468a..721dda247 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -1150,21 +1150,36 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -1177,11 +1192,20 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
diff --git a/MagickCore/type.c b/MagickCore/type.c
index 5830ff19b..eb5464f3c 100644
--- a/MagickCore/type.c
+++ b/MagickCore/type.c
@@ -1123,21 +1123,36 @@ static MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
int
bracket_depth = 0,
quote = 0;
-
+
/*
- DOCTYPE element.
+ 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;
+ quote = 0;
}
else
{
if ((*q == '"') || (*q == '\''))
- quote=(*q);
+ quote = (*q);
else
if (*q == '[')
bracket_depth++;
@@ -1150,11 +1165,20 @@ static MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
else
if ((*q == '>') && (bracket_depth == 0))
{
- q++; /* consume final '>' */
+ q++;
break;
}
}
}
+ if (*q == '\0')
+ {
+ /*
+ Detect unterminated DOCTYPE.
+ */
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ break;
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)