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