Commit 3705205e1 for imagemagick.org

commit 3705205e1424d379c2fc46c026c8560ccea0509e
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Wed May 20 22:26:20 2026 -0400

    https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-gm48-c7f2-v67p

diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index 3b2eb0bcc..f6a6d7933 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -3518,6 +3518,13 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
             }
           (void) CopyMagickString(image->filename,filename,MagickPathExtent);
         }
+      if (IsPathAuthorized(rights,filename) == MagickFalse)
+        {
+          errno=EPERM;
+          (void) ThrowMagickException(exception,GetMagickModule(),
+            PolicyError,"NotAuthorized","`%s'",filename);
+          return(MagickFalse);
+        }
     }
   if (image_info->file != (FILE *) NULL)
     {
@@ -3666,13 +3673,6 @@ MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
                 (void) SetStreamBuffering(image_info,blob_info);
               }
           }
-  if (IsPathAuthorized(rights,filename) == MagickFalse)
-    {
-      errno=EPERM;
-      (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
-        "NotAuthorized","`%s'",filename);
-      return(MagickFalse);
-    }
   blob_info->status=0;
   blob_info->error_number=0;
   if (blob_info->type != UndefinedStream)
diff --git a/MagickCore/policy.c b/MagickCore/policy.c
index acd145543..0cb4cb336 100644
--- a/MagickCore/policy.c
+++ b/MagickCore/policy.c
@@ -680,8 +680,7 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
 {
   char
     *name = (char *) NULL,
-    *pattern = (char *) NULL,
-    *real_pattern = (char *) NULL;
+    *pattern = (char *) NULL;

   const PolicyInfo
     **policies = (const PolicyInfo **) NULL;
@@ -729,17 +728,36 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
       *policy = policies[i];

     MagickBooleanType
-      match;
+      match = MagickFalse;

     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 (policy->domain != PathPolicyDomain)
+      match=GlobExpression(pattern,policy->pattern,MagickFalse);
+    else
+      {
+        char
+          *canonical_directory,
+          *canonical_path,
+          directory[MagickPathExtent];
+
+        GetPathComponent(pattern,HeadPath,directory);
+        canonical_directory=realpath_utf8(directory);
+        if (canonical_directory != (char *) NULL)
+          {
+            match=GlobExpression(canonical_directory,policy->pattern,
+              MagickFalse);
+            canonical_directory=DestroyString(canonical_directory);
+          }
+        canonical_path=realpath_utf8(pattern);
+        if ((canonical_path != (char *) NULL) && (match == MagickFalse))
+          {
+            match=GlobExpression(canonical_path,policy->pattern,MagickFalse);
+            canonical_path=DestroyString(canonical_path);
+          }
+      }
     if (match == MagickFalse)
       continue;
     matched_any=MagickTrue;
@@ -750,8 +768,6 @@ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
     pattern=DestroyString(pattern);
   if (name != (char *) NULL)
     name=DestroyString(name);
-  if (real_pattern != (char *) NULL)
-    real_pattern=DestroyString(real_pattern);
   /*
     Is rights authorized?
   */