Commit d1bf6bcf3 for imagemagick.org

commit d1bf6bcf357fef944280263892dadf84fbb2211d
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Fri May 22 18:45:19 2026 -0400

    https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-xcjm-wqff-m669

diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index d52601c3e..498f4a4ec 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -84,7 +84,7 @@
 */
 #define IsPathAuthorized(rights,filename) \
   ((IsRightsAuthorized(PathPolicyDomain,rights,filename) != MagickFalse) && \
-   ((IsRightsAuthorized(SystemPolicyDomain,rights,"symlink::follow") != MagickFalse) || \
+   ((IsRightsAuthorizedByName(SystemPolicyDomain,"symlink",rights,"follow") != MagickFalse) || \
     (is_symlink_utf8(filename) == MagickFalse)))
 #define MagickMaxBlobExtent  (8*8192)
 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
diff --git a/MagickCore/image-private.h b/MagickCore/image-private.h
index 81265022c..a9f407b4c 100644
--- a/MagickCore/image-private.h
+++ b/MagickCore/image-private.h
@@ -175,12 +175,12 @@ static inline ssize_t CastDoubleToSsizeT(const double x)
   if (value < ((double) MAGICK_SSIZE_MIN))
     {
       errno=ERANGE;
-      return(MAGICK_SSIZE_MIN);
+      return((ssize_t) MAGICK_SSIZE_MIN);
     }
   if (value >= ((double) MAGICK_SSIZE_MAX))
     {
       errno=ERANGE;
-      return(MAGICK_SSIZE_MAX);
+      return((ssize_t) MAGICK_SSIZE_MAX);
     }
   return((ssize_t) value);
 }
diff --git a/MagickCore/image.c b/MagickCore/image.c
index 65e701b00..e3a12d84e 100644
--- a/MagickCore/image.c
+++ b/MagickCore/image.c
@@ -1664,7 +1664,7 @@ static inline MagickBooleanType IsValidFormatSpecifier(const char *start,
     specifier = end[-1];

   size_t
-    length = end-start;
+    length = (size_t) (end-start);

   /*
     Is this a valid format specifier?
@@ -1742,7 +1742,7 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
               format_specifier[MagickPathExtent];

             size_t
-              length = cursor-specifier_start,
+              length = (size_t) (cursor-specifier_start),
               pattern_length;

             ssize_t
@@ -1757,7 +1757,8 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
               return(0);
             if ((p-filename+pattern_length) >= MagickPathExtent)
               return(0);
-            (void) CopyMagickString(p,pattern,MagickPathExtent-(p-filename));
+            (void) CopyMagickString(p,pattern,(size_t) (MagickPathExtent-
+              (p-filename)));
             p+=pattern_length;
             cursor++;
             continue;
@@ -1803,7 +1804,8 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
         option_length=strlen(option);
         if ((p-filename+option_length) >= MagickPathExtent)
           return(0);
-        (void) CopyMagickString(p,option,MagickPathExtent-(p-filename));
+        (void) CopyMagickString(p,option,(size_t) (MagickPathExtent-
+          (p-filename)));
         p+=option_length;
         cursor=end+1;
         continue;
diff --git a/MagickCore/policy-private.h b/MagickCore/policy-private.h
index 3acc98a83..37916eb4c 100644
--- a/MagickCore/policy-private.h
+++ b/MagickCore/policy-private.h
@@ -34,6 +34,8 @@ static const char
 #endif

 extern MagickPrivate MagickBooleanType
+  IsRightsAuthorizedByName(const PolicyDomain,const char *,const PolicyRights,
+    const char *),
   PolicyComponentGenesis(void);

 extern MagickPrivate void
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index 67c50c177..49a307ffc 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -598,7 +598,7 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
 {
   if (policy_cache == (LinkedListInfo *) NULL)
     {
-      GetMaxMemoryRequest();  /* avoid OMP deadlock */
+      (void) GetMaxMemoryRequest();  /* avoid OMP deadlock */
       if (policy_semaphore == (SemaphoreInfo *) NULL)
         ActivateSemaphoreInfo(&policy_semaphore);
       LockSemaphoreInfo(policy_semaphore);
@@ -626,7 +626,7 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
 %  The format of the IsRightsAuthorized method is:
 %
 %      MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
-%        const PolicyRights rights,const char *qualified_pattern)
+%        const PolicyRights rights,const char *pattern)
 %
 %  A description of each parameter follows:
 %
@@ -634,58 +634,20 @@ static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
 %
 %    o rights: the policy rights.
 %
-%    o qualified_pattern: the pattern.
+%    o pattern: the pattern.
 %
 */

-static inline MagickBooleanType ParseNamespace(const char *qualified_pattern,
-  char **name,char **pattern)
-{
-  const char
-    *p,
-    *separator;
-
-  size_t
-    length;
-
-  if ((qualified_pattern == (const char *) NULL) || (name == (char **) NULL) ||
-      (pattern == (char **) NULL))
-    return(MagickFalse);
-  *name=(char *) NULL;
-  *pattern=(char *) NULL;
-  separator=strstr(qualified_pattern,"::");
-  if (separator == (const char *) NULL)
-    {
-      *pattern=AcquireString(qualified_pattern);
-      return(*pattern != (char *) NULL ? MagickTrue : MagickFalse);
-    }
-  length=(size_t) (separator-qualified_pattern);
-  *name=(char *) AcquireQuantumMemory(length+1,sizeof(char));
-  if (*name == (char *) NULL)
-    return(MagickFalse);
-  (void) CopyMagickString(*name,qualified_pattern,length+1);
-  p=separator+2;
-  *pattern=AcquireString(p);
-  if (*pattern == (char *) NULL)
-    {
-      *name=DestroyString(*name);
-      *name=(char *) NULL;
-      return(MagickFalse);
-    }
-  return(MagickTrue);
-}
-
-MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
-  const PolicyRights rights,const char *qualified_pattern)
+MagickPrivate MagickBooleanType IsRightsAuthorizedByName(
+  const PolicyDomain domain,const char *name,const PolicyRights rights,
+  const char *pattern)
 {
   char
     *canonical_directory = (char *) NULL,
     *canonical_path = (char *) NULL,
     *canonical_candidate = (char *) NULL,
     directory[MagickPathExtent],
-    filename[MagickPathExtent],
-    *name = (char *) NULL,
-    *pattern = (char *) NULL;
+    filename[MagickPathExtent];

   const PolicyInfo
     **policies = (const PolicyInfo **) NULL;
@@ -710,8 +672,7 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
     (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
       "Domain: %s; rights=%s; pattern=\"%s\" ...",
       CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
-      CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),
-      qualified_pattern);
+      CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
   /*
     Load policies.
   */
@@ -720,11 +681,6 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
   exception=DestroyExceptionInfo(exception);
   if (policies == (const PolicyInfo **) NULL)
     return(MagickTrue);
-  if (ParseNamespace(qualified_pattern,&name,&pattern) == MagickFalse)
-    {
-      policies=(const PolicyInfo **) RelinquishMagickMemory((void *) policies);
-      return(MagickFalse);
-    }
   /*
     Evaluate policies in order; last match wins.
   */
@@ -782,10 +738,6 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
     effective_rights=policy->rights;
   }
   policies=(const PolicyInfo **) RelinquishMagickMemory((void *) policies);
-  if (pattern != (char *) NULL)
-    pattern=DestroyString(pattern);
-  if (name != (char *) NULL)
-    name=DestroyString(name);
   if (canonical_directory != (char *) NULL)
     canonical_directory=DestroyString(canonical_directory);
   if (canonical_candidate != (char *) NULL)
@@ -797,15 +749,23 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
   */
   if (matched_any == MagickFalse)
     return(MagickTrue);
-  if ((rights & ReadPolicyRights) && !(effective_rights & ReadPolicyRights))
+  if (((rights & ReadPolicyRights) != 0) &&
+      ((effective_rights & ReadPolicyRights) == 0))
    return(MagickFalse);
-  if ((rights & WritePolicyRights) && !(effective_rights & WritePolicyRights))
+  if (((rights & WritePolicyRights) != 0) &&
+      ((effective_rights & WritePolicyRights) == 0))
    return(MagickFalse);
-  if ((rights & ExecutePolicyRights) &&
-      !(effective_rights & ExecutePolicyRights))
+  if (((rights & ExecutePolicyRights) != 0) &&
+      ((effective_rights & ExecutePolicyRights) == 0))
     return(MagickFalse);
   return(MagickTrue);
 }
+
+MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
+  const PolicyRights rights,const char *pattern)
+{
+  return(IsRightsAuthorizedByName(domain,(const char *) NULL,rights,pattern));
+}

 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/MagickCore/token-private.h b/MagickCore/token-private.h
index ebf851aa3..9989d8102 100644
--- a/MagickCore/token-private.h
+++ b/MagickCore/token-private.h
@@ -139,7 +139,7 @@ static inline unsigned char *ConvertMacRomanToUTF8(
   {
     c=(*p);
     if (c > 128)
-      c=macroman_unicode[c-128];
+      c=(int) macroman_unicode[c-128];
     if ((c & 0x80) == 0)
       *q++=(unsigned char) c;
     else