Commit 3a9639c0b for imagemagick.org
commit 3a9639c0bd21f61f22fcce4c5f6838f1f0d8f738
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Sun Oct 25 09:30:23 2026 +0100
Added new method to sanitize filenames and use that for GHSA-2pc3-3339-3qc9.
diff --git a/MagickCore/methods.h b/MagickCore/methods.h
index f04fc47f9..08d771b74 100644
--- a/MagickCore/methods.h
+++ b/MagickCore/methods.h
@@ -1077,6 +1077,7 @@ extern "C" {
#define RotationalBlurImage PrependMagickMethod(RotationalBlurImage)
#define SampleImage PrependMagickMethod(SampleImage)
#define SanitizeString PrependMagickMethod(SanitizeString)
+#define SanitizeStringForIdentifier PrependMagickMethod(SanitizeStringForIdentifier)
#define ScaleGeometryKernelInfo PrependMagickMethod(ScaleGeometryKernelInfo)
#define ScaleImage PrependMagickMethod(ScaleImage)
#define ScaleKernelInfo PrependMagickMethod(ScaleKernelInfo)
diff --git a/MagickCore/string.c b/MagickCore/string.c
index cac00ea52..f0406a830 100644
--- a/MagickCore/string.c
+++ b/MagickCore/string.c
@@ -1583,6 +1583,53 @@ MagickExport void ResetStringInfo(StringInfo *string_info)
% %
% %
% %
+% S a n i t i z e S t r i n g F o r I d e n t i f i e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SanitizeStringForIdentifier() returns a new string suitable for use as a C
+% identifier. Invalid characters are replaced with underscores. An empty
+% source string becomes a single underscore.
+%
+% Free the sanitized string with DestroyString().
+%
+% The format of the SanitizeStringForIdentifier method is:
+%
+% char *SanitizeStringForIdentifier(const char *source)
+%
+% A description of each parameter follows:
+%
+% o source: A character string.
+%
+*/
+MagickExport char *SanitizeStringForIdentifier(const char *source)
+{
+ char
+ *p,
+ *sanitize_source;
+
+ static const char
+ letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_",
+ digits[] = "0123456789";
+
+ assert(source != (const char *) NULL);
+ sanitize_source=AcquireString(*source == '\0' ? "_" : source);
+ if (strchr(letters,(int) ((unsigned char) *sanitize_source)) == (char *) NULL)
+ *sanitize_source='_';
+ for (p=sanitize_source+1; *p != '\0'; p++)
+ if ((strchr(letters,(int) ((unsigned char) *p)) == (char *) NULL) &&
+ (strchr(digits,(int) ((unsigned char) *p)) == (char *) NULL))
+ *p='_';
+ return(sanitize_source);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% S a n t i z e S t r i n g %
% %
% %
diff --git a/MagickCore/string_.h b/MagickCore/string_.h
index e562a8a1d..4b1f5cd0d 100644
--- a/MagickCore/string_.h
+++ b/MagickCore/string_.h
@@ -50,6 +50,7 @@ extern MagickExport char
*FileToString(const char *,const size_t,ExceptionInfo *),
*GetEnvironmentValue(const char *),
*SanitizeString(const char *),
+ *SanitizeStringForIdentifier(const char *),
*StringInfoToDigest(const StringInfo *),
*StringInfoToHexString(const StringInfo *),
*StringInfoToString(const StringInfo *),
diff --git a/coders/magick.c b/coders/magick.c
index 55f5c73f9..712263605 100644
--- a/coders/magick.c
+++ b/coders/magick.c
@@ -13288,8 +13288,7 @@ static MagickBooleanType WriteMAGICKImage(const ImageInfo *image_info,
return(status);
}
(void) WriteBlobString(image,"/*\n");
- sanitized_filename=AcquireString(image->filename);
- (void) SubstituteString(&sanitized_filename,"*/","??");
+ sanitized_filename=SanitizeStringForIdentifier(image->filename);
(void) FormatLocaleString(buffer,MagickPathExtent," %s (%s).\n",
sanitized_filename,write_info->magick);
sanitized_filename=DestroyString(sanitized_filename);
diff --git a/coders/xbm.c b/coders/xbm.c
index 108f7ad6f..3f86ac8ac 100644
--- a/coders/xbm.c
+++ b/coders/xbm.c
@@ -516,7 +516,8 @@ static MagickBooleanType WriteXBMImage(const ImageInfo *image_info,Image *image,
{
char
basename[MagickPathExtent],
- buffer[MagickPathExtent];
+ buffer[MagickPathExtent],
+ *sanitized_filename;
MagickBooleanType
status;
@@ -555,14 +556,16 @@ static MagickBooleanType WriteXBMImage(const ImageInfo *image_info,Image *image,
Write X bitmap header.
*/
GetPathComponent(image->filename,BasePath,basename);
+ sanitized_filename=SanitizeStringForIdentifier(basename);
(void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_width %.17g\n",
- basename,(double) image->columns);
+ sanitized_filename,(double) image->columns);
(void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
(void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_height %.17g\n",
- basename,(double) image->rows);
+ sanitized_filename,(double) image->rows);
(void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
(void) FormatLocaleString(buffer,MagickPathExtent,
- "static char %s_bits[] = {\n",basename);
+ "static char %s_bits[] = {\n",sanitized_filename);
+ sanitized_filename=DestroyString(sanitized_filename);
(void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
(void) CopyMagickString(buffer," ",MagickPathExtent);
(void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
diff --git a/coders/xpm.c b/coders/xpm.c
index 4437083fd..b6002a998 100644
--- a/coders/xpm.c
+++ b/coders/xpm.c
@@ -678,7 +678,8 @@ static MagickBooleanType WritePICONImage(const ImageInfo *image_info,
buffer[MagickPathExtent],
basename[MagickPathExtent],
name[MagickPathExtent],
- symbol[MagickPathExtent];
+ symbol[MagickPathExtent],
+ *sanitized_filename;
Image
*affinity_image,
@@ -836,8 +837,10 @@ static MagickBooleanType WritePICONImage(const ImageInfo *image_info,
*/
(void) WriteBlobString(image,"/* XPM */\n");
GetPathComponent(picon->filename,BasePath,basename);
+ sanitized_filename=SanitizeStringForIdentifier(basename);
(void) FormatLocaleString(buffer,MagickPathExtent,
- "static const char *%.1024s[] = {\n",basename);
+ "static const char *%.1024s[] = {\n",sanitized_filename);
+ sanitized_filename=DestroyString(sanitized_filename);
(void) WriteBlobString(image,buffer);
(void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n");
(void) FormatLocaleString(buffer,MagickPathExtent,
@@ -950,7 +953,8 @@ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image,
buffer[MagickPathExtent],
basename[MagickPathExtent],
name[MagickPathExtent],
- symbol[MagickPathExtent];
+ symbol[MagickPathExtent],
+ *sanitized_filename;
const Quantum
*p;
@@ -1062,18 +1066,10 @@ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image,
*/
(void) WriteBlobString(image,"/* XPM */\n");
GetPathComponent(image->filename,BasePath,basename);
- if (isalnum((int) ((unsigned char) *basename)) == 0)
- {
- (void) FormatLocaleString(buffer,MagickPathExtent,"xpm_%.1024s",basename);
- (void) CopyMagickString(basename,buffer,MagickPathExtent);
- }
- if (isalpha((int) ((unsigned char) basename[0])) == 0)
- basename[0]='_';
- for (i=1; basename[i] != '\0'; i++)
- if (isalnum((int) ((unsigned char) basename[i])) == 0)
- basename[i]='_';
+ sanitized_filename=SanitizeStringForIdentifier(basename);
(void) FormatLocaleString(buffer,MagickPathExtent,
- "static char *%.1024s[] = {\n",basename);
+ "static char *%.1024s[] = {\n",sanitized_filename);
+ sanitized_filename=DestroyString(sanitized_filename);
(void) WriteBlobString(image,buffer);
(void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n");
(void) FormatLocaleString(buffer,MagickPathExtent,