Commit 8309dc92a for imagemagick.org
commit 8309dc92a18722a9ccc4bb9c848ac2d01426cfe5
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Thu Sep 3 21:32:06 2026 +0200
Trim labels to prevent code injection (GHSA-p6j5-2qwh-6486)
diff --git a/MagickCore/annotate.c b/MagickCore/annotate.c
index 5624a72e4..2773f415f 100644
--- a/MagickCore/annotate.c
+++ b/MagickCore/annotate.c
@@ -2292,7 +2292,7 @@ static MagickBooleanType RenderPostscript(Image *image,
(void) FormatLocaleFile(file,"[%g %g %g %g 0 0] concat\n",
draw_info->affine.sx,-draw_info->affine.rx,-draw_info->affine.ry,
draw_info->affine.sy);
- text=EscapeParenthesis(draw_info->text);
+ text=EscapeParenthesis(draw_info->text,MAGICK_SIZE_MAX,exception);
if (identity == MagickFalse)
(void) FormatLocaleFile(file,"(%s) stringwidth pop -0.5 mul -0.5 rmoveto\n",
text);
diff --git a/coders/ghostscript-private.h b/coders/ghostscript-private.h
index d1d38f3cb..ee64ab13c 100644
--- a/coders/ghostscript-private.h
+++ b/coders/ghostscript-private.h
@@ -278,7 +278,8 @@ static inline void ReadGhostScriptXMPProfile(MagickByteBuffer *buffer,
SetStringInfoLength(*profile,(size_t) count);
}
-static inline char *EscapeParenthesis(const char *source)
+static inline char *EscapeParenthesis(const char *source,
+ const size_t max_length,ExceptionInfo *exception)
{
char
*destination;
@@ -287,6 +288,7 @@ static inline char *EscapeParenthesis(const char *source)
*q;
const char
+ *end,
*p;
size_t
@@ -294,16 +296,21 @@ static inline char *EscapeParenthesis(const char *source)
assert(source != (const char *) NULL);
length=0;
+ end=source;
for (p=source; *p != '\0'; p++)
{
- if ((*p == '\\') || (*p == '(') || (*p == ')'))
- {
- if (~length < 1)
- ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
- length++;
- }
- length++;
+ size_t
+ count;
+
+ count=((*p == '\\') || (*p == '(') || (*p == ')')) ? 2 : 1;
+ if ((~length < count) || ((length+count) > max_length))
+ break;
+ length+=count;
+ end=p+1;
}
+ if (*end != '\0')
+ (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
+ "LabelTruncated","`%g'",(double) max_length);
destination=(char *) NULL;
if (~length >= (MagickPathExtent-1))
destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
@@ -312,7 +319,7 @@ static inline char *EscapeParenthesis(const char *source)
ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
*destination='\0';
q=destination;
- for (p=source; *p != '\0'; p++)
+ for (p=source; p < end; p++)
{
if ((*p == '\\') || (*p == '(') || (*p == ')'))
*q++='\\';
diff --git a/coders/pdf.c b/coders/pdf.c
index f16069e86..11440d37a 100644
--- a/coders/pdf.c
+++ b/coders/pdf.c
@@ -1256,7 +1256,7 @@ static const char *GetPDFKeywords(const ImageInfo *image_info)
}
static void WritePDFValue(Image* image,const char *keyword,
- const char *value,const MagickBooleanType is_pdfa)
+ const char *value,const MagickBooleanType is_pdfa,ExceptionInfo *exception)
{
char
*escaped;
@@ -1274,7 +1274,7 @@ static void WritePDFValue(Image* image,const char *keyword,
return;
if (is_pdfa != MagickFalse)
{
- escaped=EscapeParenthesis(value);
+ escaped=EscapeParenthesis(value,MAGICK_SIZE_MAX,exception);
(void) WriteBlobString(image,"/");
(void) WriteBlobString(image,keyword);
(void) WriteBlobString(image," (");
@@ -1912,7 +1912,7 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image,
(double) geometry.x,(double) (geometry.y+(ssize_t) geometry.height+
i*pointsize+12));
(void) WriteBlobString(image,buffer);
- escape=EscapeParenthesis(labels[i]);
+ escape=EscapeParenthesis(labels[i],MAGICK_SIZE_MAX,exception);
(void) FormatLocaleString(buffer,MagickPathExtent,"(%s) Tj\n",escape);
escape=DestroyString(escape);
(void) WriteBlobString(image,buffer);
@@ -3168,12 +3168,12 @@ static MagickBooleanType WritePDFImage(const ImageInfo *image_info,Image *image,
object);
(void) WriteBlobString(image,buffer);
(void) WriteBlobString(image,"<<\n");
- WritePDFValue(image,"Title",GetPDFTitle(image_info,basename),is_pdfa);
- WritePDFValue(image,"Author",GetPDFAuthor(image_info),is_pdfa);
- WritePDFValue(image,"Creator",GetPDFCreator(image_info),is_pdfa);
- WritePDFValue(image,"Producer",GetPDFProducer(image_info),is_pdfa);
- WritePDFValue(image,"Subject",GetPDFSubject(image_info),is_pdfa);
- WritePDFValue(image,"Keywords",GetPDFKeywords(image_info),is_pdfa);
+ WritePDFValue(image,"Title",GetPDFTitle(image_info,basename),is_pdfa,exception);
+ WritePDFValue(image,"Author",GetPDFAuthor(image_info),is_pdfa,exception);
+ WritePDFValue(image,"Creator",GetPDFCreator(image_info),is_pdfa,exception);
+ WritePDFValue(image,"Producer",GetPDFProducer(image_info),is_pdfa,exception);
+ WritePDFValue(image,"Subject",GetPDFSubject(image_info),is_pdfa,exception);
+ WritePDFValue(image,"Keywords",GetPDFKeywords(image_info),is_pdfa,exception);
seconds=GetPdfCreationDate(image_info,image);
GetMagickUTCTime(&seconds,&utc_time);
(void) FormatLocaleString(temp,MagickPathExtent,"D:%04d%02d%02d%02d%02d%02d",
diff --git a/coders/ps.c b/coders/ps.c
index 02a90746c..5fe273cad 100644
--- a/coders/ps.c
+++ b/coders/ps.c
@@ -1857,7 +1857,7 @@ static MagickBooleanType WritePSImage(const ImageInfo *image_info,Image *image,
char
*escape;
- escape=EscapeParenthesis(labels[i]);
+ escape=EscapeParenthesis(labels[i],510,exception);
(void) FormatLocaleString(buffer,MagickPathExtent,"%s \n",escape);
escape=DestroyString(escape);
(void) WriteBlobString(image,buffer);
diff --git a/coders/ps2.c b/coders/ps2.c
index 2d03d72d8..82822cedd 100644
--- a/coders/ps2.c
+++ b/coders/ps2.c
@@ -793,7 +793,7 @@ static MagickBooleanType WritePS2Image(const ImageInfo *image_info,Image *image,
char
*escape;
- escape=EscapeParenthesis(labels[i]);
+ escape=EscapeParenthesis(labels[i],510,exception);
(void) FormatLocaleString(buffer,MagickPathExtent,"%s \n",escape);
escape=DestroyString(escape);
(void) WriteBlobString(image,buffer);
diff --git a/coders/ps3.c b/coders/ps3.c
index acc814f6e..d3be0cfa9 100644
--- a/coders/ps3.c
+++ b/coders/ps3.c
@@ -1296,7 +1296,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image,
char
*escape;
- escape=EscapeParenthesis(labels[i]);
+ escape=EscapeParenthesis(labels[i],510,exception);
if (compression != NoCompression)
{
for (j=0; escape[j] != '\0'; j++)