Commit 9051eb438 for imagemagick.org
commit 9051eb4387e78879d67e5a13611b6b621544959b
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sun Apr 19 10:31:51 2026 -0400
evaluate each requested right independently and combine them
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index 29d5070cb..cc58bfa28 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -413,7 +413,7 @@ MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
const PolicyInfo
*policy;
- policy=(const PolicyInfo *)p->value;
+ policy=(const PolicyInfo *) p->value;
if ((policy->stealth == MagickFalse) &&
(GlobExpression(policy->name,pattern,MagickFalse) != MagickFalse))
policies[i++]=policy;
@@ -684,17 +684,22 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
*real_pattern = (char *) NULL;
const PolicyInfo
- *policy_info;
+ **policies = (const PolicyInfo **) NULL;
ExceptionInfo
*exception;
MagickBooleanType
- authorized = MagickTrue,
- match;
+ matched_any = MagickFalse;
- ElementInfo
- *p;
+ PolicyRights
+ effective_rights = AllPolicyRights; /* rights authorized unless denied */
+
+ size_t
+ count = 0;
+
+ ssize_t
+ i;
if ((GetLogEventMask() & PolicyEvent) != 0)
(void) LogMagickEvent(PolicyEvent,GetMagickModule(),
@@ -702,54 +707,63 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),
qualified_pattern);
+ /*
+ Load policies.
+ */
exception=AcquireExceptionInfo();
- policy_info=GetPolicyInfo("*",exception);
+ policies=GetPolicyInfoList("*",&count,exception);
exception=DestroyExceptionInfo(exception);
- if (policy_info == (PolicyInfo *) NULL)
+ if (policies == (const PolicyInfo **) NULL)
return(MagickTrue);
if (ParseNamespace(qualified_pattern,&name,&pattern) == MagickFalse)
return(MagickFalse);
- LockSemaphoreInfo(policy_semaphore);
- p=GetHeadElementInLinkedList(policy_cache);
- while (p != (ElementInfo *) NULL)
+ /*
+ Evaluate policies in order; last match wins.
+ */
+ for (i=0; i < (ssize_t) count; i++)
{
const PolicyInfo
- *policy;
+ *policy = policies[i];
- policy=(const PolicyInfo *) p->value;
- if ((policy->domain == domain) &&
- ((name == (char *) NULL) || (LocaleCompare(name,policy->name) == 0)))
- {
- if ((policy->domain == PathPolicyDomain) &&
- (real_pattern == (const char *) NULL))
- real_pattern=realpath_utf8(pattern);
- if (real_pattern != (char*) NULL)
- match=GlobExpression(real_pattern,policy->pattern,MagickFalse);
- else
- match=GlobExpression(pattern,policy->pattern,MagickFalse);
- if (match != MagickFalse)
- {
- if ((rights & ReadPolicyRights) != 0)
- authorized=(policy->rights & ReadPolicyRights) != 0 ?
- MagickTrue : MagickFalse;
- if ((rights & WritePolicyRights) != 0)
- authorized=(policy->rights & WritePolicyRights) != 0 ?
- MagickTrue : MagickFalse;
- if ((rights & ExecutePolicyRights) != 0)
- authorized=(policy->rights & ExecutePolicyRights) != 0 ?
- MagickTrue : MagickFalse;
- }
- }
- p=p->next;
+ MagickBooleanType
+ match;
+
+ if (policy->domain != domain)
+ continue;
+ if ((name != (char *) NULL) && (LocaleCompare(name,policy->name) != 0))
+ continue;
+ if ((policy->domain == PathPolicyDomain) &&
+ (real_pattern == (const char *) NULL))
+ real_pattern=realpath_utf8(pattern);
+ match=GlobExpression(real_pattern != (char*) NULL ? real_pattern : pattern,
+ policy->pattern,MagickFalse);
+ if (match == MagickFalse)
+ continue;
+ matched_any=MagickTrue;
+ effective_rights=policy->rights;
}
- UnlockSemaphoreInfo(policy_semaphore);
+ policies=(const PolicyInfo **) RelinquishMagickMemory((void *) policies);
if (pattern != (char *) NULL)
pattern=DestroyString(pattern);
if (name != (char *) NULL)
name=DestroyString(name);
if (real_pattern != (char *) NULL)
real_pattern=DestroyString(real_pattern);
- return(authorized);
+ /*
+ Is rights authorized?
+ */
+ if (matched_any == MagickFalse)
+ return MagickTrue;
+ if ((rights & ReadPolicyRights) &&
+ !(effective_rights & ReadPolicyRights))
+ return(MagickFalse);
+ if ((rights & WritePolicyRights) &&
+ !(effective_rights & WritePolicyRights))
+ return(MagickFalse);
+ if ((rights & ExecutePolicyRights) &&
+ !(effective_rights & ExecutePolicyRights))
+ return(MagickFalse);
+ return(MagickTrue);
}
/*