Commit 1926ccf11 for imagemagick.org
commit 1926ccf119141c26274c120d1899dffae19b0c71
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sat Sep 5 13:07:43 2026 -0400
https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-jjp4-3fwf-393j
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index 35d553f24..32781f89e 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -1080,6 +1080,28 @@ MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
% o exception: return any errors or warnings in this structure.
%
*/
+
+static void *DestroyPolicyElement(void *policy_info)
+{
+ PolicyInfo
+ *p;
+
+ p=(PolicyInfo *) policy_info;
+ if (p->exempt == MagickFalse)
+ {
+ if (p->value != (char *) NULL)
+ p->value=DestroyString(p->value);
+ if (p->pattern != (char *) NULL)
+ p->pattern=DestroyString(p->pattern);
+ if (p->name != (char *) NULL)
+ p->name=DestroyString(p->name);
+ if (p->path != (char *) NULL)
+ p->path=DestroyString(p->path);
+ }
+ p=(PolicyInfo *) RelinquishMagickMemory(p);
+ return((void *) NULL);
+}
+
static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
const char *policy,const char *filename,const size_t depth,
ExceptionInfo *exception)
@@ -1122,11 +1144,56 @@ static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
(void) CopyMagickString(keyword,token,MagickPathExtent);
if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
{
+ char
+ quote = '\0';
+
+ ssize_t
+ subset_depth = 0;
+
/*
- Docdomain element.
+ Skip to the end of the DOCTYPE declaration.
*/
- while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
- (void) GetNextToken(q,&q,extent,token);
+ while (*q != '\0')
+ {
+ if (quote != '\0')
+ {
+ if (*q == quote)
+ quote='\0';
+ q++;
+ continue;
+ }
+ if ((*q == '\'') || (*q == '"'))
+ {
+ quote=(*q);
+ q++;
+ continue;
+ }
+ if (*q == '[')
+ {
+ subset_depth++;
+ q++;
+ continue;
+ }
+ if ((*q == ']') && (subset_depth > 0))
+ {
+ subset_depth--;
+ q++;
+ continue;
+ }
+ if ((*q == '>') && (subset_depth == 0))
+ {
+ q++;
+ break;
+ }
+ q++;
+ }
+ if (*q == '\0')
+ {
+ ThrowMagickException(exception,GetMagickModule(),
+ ConfigureError,"UnterminatedDOCTYPE","`%s'",filename);
+ policy_cache=DestroyLinkedList(policy_cache,DestroyPolicyElement);
+ return(MagickFalse);
+ }
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
@@ -1326,28 +1393,6 @@ MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
% PolicyComponentTerminus(void)
%
*/
-
-static void *DestroyPolicyElement(void *policy_info)
-{
- PolicyInfo
- *p;
-
- p=(PolicyInfo *) policy_info;
- if (p->exempt == MagickFalse)
- {
- if (p->value != (char *) NULL)
- p->value=DestroyString(p->value);
- if (p->pattern != (char *) NULL)
- p->pattern=DestroyString(p->pattern);
- if (p->name != (char *) NULL)
- p->name=DestroyString(p->name);
- if (p->path != (char *) NULL)
- p->path=DestroyString(p->path);
- }
- p=(PolicyInfo *) RelinquishMagickMemory(p);
- return((void *) NULL);
-}
-
MagickPrivate void PolicyComponentTerminus(void)
{
if (policy_semaphore == (SemaphoreInfo *) NULL)
@@ -1435,7 +1480,7 @@ MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy,
return(MagickFalse);
LockSemaphoreInfo(policy_semaphore);
status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception);
- UnlockSemaphoreInfo(policy_semaphore)
+ UnlockSemaphoreInfo(policy_semaphore);
if (status == MagickFalse)
return(status);
/*