Commit 11313ac54 for imagemagick.org

commit 11313ac549e3466edaa47012616b0db4def5c22b
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sat Oct 24 18:19:38 2026 +0200

    Added new security option that can be used to limit the number of profiles an image can have (GHSA-2h6m-67xh-cm4p)

diff --git a/MagickCore/profile-private.h b/MagickCore/profile-private.h
index 96c7e56b4..03d99c378 100644
--- a/MagickCore/profile-private.h
+++ b/MagickCore/profile-private.h
@@ -27,6 +27,9 @@ extern "C" {
 extern MagickExport MagickBooleanType
   SetImageProfilePrivate(Image *,StringInfo *,ExceptionInfo *);

+extern MagickExport size_t
+  GetMaxProfileCount(void);
+
 extern MagickExport StringInfo
   *AcquireProfileStringInfo(const char *,const size_t length,ExceptionInfo *),
   *BlobToProfileStringInfo(const char *,const void *blob,const size_t length,
diff --git a/MagickCore/profile.c b/MagickCore/profile.c
index bf384281b..a7b11d5a3 100644
--- a/MagickCore/profile.c
+++ b/MagickCore/profile.c
@@ -56,6 +56,7 @@
 #include "MagickCore/option.h"
 #include "MagickCore/option-private.h"
 #include "MagickCore/pixel-accessor.h"
+#include "MagickCore/policy.h"
 #include "MagickCore/profile.h"
 #include "MagickCore/profile-private.h"
 #include "MagickCore/property.h"
@@ -91,6 +92,12 @@ static MagickBooleanType
 static void
   WriteTo8BimProfile(Image *,const char*,const StringInfo *);

+/*
+  Global declarations.
+*/
+static size_t
+  max_profile_count = 0;
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -350,6 +357,51 @@ MagickExport const StringInfo *GetImageProfile(const Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
++   G e t M a x P r o f i l e C o u n t                                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  GetMaxProfileCount() returns the max profile count value.
+%
+%  The format of the GetMaxProfileCount method is:
+%
+%      size_t GetMaxProfileCount(void)
+%
+*/
+static size_t GetMaxProfileCountFromPolicy(void)
+{
+  char
+    *value;
+
+  size_t
+    max=(size_t) MAGICK_SSIZE_MAX;
+
+  value=GetPolicyValue("system:max-profile-count");
+  if (value != (char *) NULL)
+    {
+      /*
+        The security policy sets a max profile count limit.
+      */
+      max=StringToSizeType(value,100.0);
+      value=DestroyString(value);
+    }
+  return(MagickMin(max,(size_t) MAGICK_SSIZE_MAX));
+}
+
+MagickExport size_t GetMaxProfileCount(void)
+{
+  if (max_profile_count == 0)
+    max_profile_count=GetMaxProfileCountFromPolicy();
+  return(max_profile_count);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   G e t N e x t I m a g e P r o f i l e                                     %
 %                                                                             %
 %                                                                             %
@@ -2042,6 +2094,14 @@ static MagickBooleanType SetImageProfileInternal(Image *image,const char *name,
   assert(name != (const char *) NULL);
   if (IsEventLogging() != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  if ((image->profiles != (SplayTreeInfo*) NULL) &&
+      (GetNumberOfNodesInSplayTree((SplayTreeInfo*) image->profiles) >= GetMaxProfileCount()))
+    {
+      (void) ThrowMagickException(exception,GetMagickModule(),
+        ResourceLimitWarning,"MaximumProfilesExceeded","`%s'",name);
+      profile=DestroyStringInfo(profile);
+      return(MagickFalse);
+    }
   length=GetStringInfoLength(profile);
   if ((length == 0) || (length > GetMaxProfileSize()))
     {