Commit 9db96365e for imagemagick.org
commit 9db96365ecab5de69cdec81b9359672b3a827aaa
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Sun Feb 15 16:52:24 2026 +0100
Escape more strings when creating an MVG file in the internal SVG decoder (GHSA-xpg8-7m6m-jf56)
diff --git a/coders/svg.c b/coders/svg.c
index e3d3a4c41..52220081e 100644
--- a/coders/svg.c
+++ b/coders/svg.c
@@ -880,6 +880,19 @@ static char **SVGKeyValuePairs(SVGInfo *svg_info,const int key_sentinel,
return(tokens);
}
+static inline char *SVGEscapeString(const char* value)
+{
+ char
+ *escaped_value,
+ *p;
+
+ escaped_value=EscapeString(value,'\"');
+ for (p=escaped_value; *p != '\0'; p++)
+ if (*p == '\n')
+ *p=' ';
+ return(escaped_value);
+}
+
static void SVGProcessStyleElement(SVGInfo *svg_info,const xmlChar *name,
const char *style)
{
@@ -888,8 +901,7 @@ static void SVGProcessStyleElement(SVGInfo *svg_info,const xmlChar *name,
*color,
*keyword,
**tokens,
- *units,
- *value;
+ *units;
size_t
number_tokens;
@@ -904,10 +916,10 @@ static void SVGProcessStyleElement(SVGInfo *svg_info,const xmlChar *name,
for (i=0; i < ((ssize_t) number_tokens-1); i+=2)
{
keyword=(char *) tokens[i];
- value=(char *) tokens[i+1];
if (LocaleCompare(keyword,"font-size") != 0)
continue;
- svg_info->pointsize=GetUserSpaceCoordinateValue(svg_info,0,value);
+ svg_info->pointsize=GetUserSpaceCoordinateValue(svg_info,0,
+ (char *) tokens[i+1]);
(void) FormatLocaleFile(svg_info->file,"font-size %g\n",
svg_info->pointsize);
}
@@ -915,8 +927,11 @@ static void SVGProcessStyleElement(SVGInfo *svg_info,const xmlChar *name,
units=AcquireString("userSpaceOnUse");
for (i=0; i < ((ssize_t) number_tokens-1); i+=2)
{
+ char
+ *value;
+
keyword=(char *) tokens[i];
- value=(char *) tokens[i+1];
+ value=SVGEscapeString((const char *) tokens[i+1]);
(void) LogMagickEvent(CoderEvent,GetMagickModule()," %s: %s",keyword,
value);
switch (*keyword)
@@ -1201,6 +1216,7 @@ static void SVGProcessStyleElement(SVGInfo *svg_info,const xmlChar *name,
default:
break;
}
+ value=DestroyString(value);
}
if (units != (char *) NULL)
units=DestroyString(units);
@@ -1234,8 +1250,7 @@ static void SVGStartElement(void *context,const xmlChar *name,
const char
*keyword,
- *p,
- *value;
+ *p;
size_t
number_tokens;
@@ -1279,7 +1294,6 @@ static void SVGStartElement(void *context,const xmlChar *name,
*id='\0';
*token='\0';
*background='\0';
- value=(const char *) NULL;
if ((LocaleCompare((char *) name,"image") == 0) ||
(LocaleCompare((char *) name,"pattern") == 0) ||
(LocaleCompare((char *) name,"rect") == 0) ||
@@ -1292,8 +1306,11 @@ static void SVGStartElement(void *context,const xmlChar *name,
if (attributes != (const xmlChar **) NULL)
for (i=0; (attributes[i] != (const xmlChar *) NULL); i+=2)
{
+ char
+ *value;
+
keyword=(const char *) attributes[i];
- value=(const char *) attributes[i+1];
+ value=SVGEscapeString((const char *) attributes[i+1]);
switch (*keyword)
{
case 'C':
@@ -1420,6 +1437,7 @@ static void SVGStartElement(void *context,const xmlChar *name,
default:
break;
}
+ value=DestroyString(value);
}
if (strchr((char *) name,':') != (char *) NULL)
{
@@ -1644,8 +1662,11 @@ static void SVGStartElement(void *context,const xmlChar *name,
if (attributes != (const xmlChar **) NULL)
for (i=0; (attributes[i] != (const xmlChar *) NULL); i+=2)
{
+ char
+ *value;
+
keyword=(const char *) attributes[i];
- value=(const char *) attributes[i+1];
+ value=SVGEscapeString((const char *) attributes[i+1]);
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" %s = %s",keyword,value);
switch (*keyword)
@@ -2495,6 +2516,7 @@ static void SVGStartElement(void *context,const xmlChar *name,
default:
break;
}
+ value=DestroyString(value);
}
if (LocaleCompare((const char *) name,"svg") == 0)
{
@@ -2599,19 +2621,9 @@ static void SVGEndElement(void *context,const xmlChar *name)
}
if (LocaleCompare((const char *) name,"desc") == 0)
{
- char
- *p;
-
if (*svg_info->text == '\0')
break;
- (void) fputc('#',svg_info->file);
- for (p=svg_info->text; *p != '\0'; p++)
- {
- (void) fputc(*p,svg_info->file);
- if (*p == '\n')
- (void) fputc('#',svg_info->file);
- }
- (void) fputc('\n',svg_info->file);
+ (void) FormatLocaleFile(svg_info->file,"# %s\n",svg_info->text);
*svg_info->text='\0';
break;
}
@@ -2661,7 +2673,6 @@ static void SVGEndElement(void *context,const xmlChar *name)
if (LocaleCompare((const char *) name,"image") == 0)
{
char
- *text,
thread_filename[MagickPathExtent];
Image
@@ -2693,12 +2704,10 @@ static void SVGEndElement(void *context,const xmlChar *name)
if (image != (Image *) NULL)
image=DestroyImage(image);
(void) DeleteNodeFromSplayTree(svg_tree,thread_filename);
- text=EscapeString(svg_info->url,'\"');
(void) FormatLocaleFile(svg_info->file,
"image Over %g,%g %g,%g \"%s\"\n",svg_info->bounds.x,
svg_info->bounds.y,svg_info->bounds.width,svg_info->bounds.height,
- text);
- text=DestroyString(text);
+ svg_info->url);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
break;
}
@@ -2911,15 +2920,11 @@ static void SVGEndElement(void *context,const xmlChar *name)
{
if (LocaleCompare((char *) name,"use") == 0)
{
- char
- *text;
-
if ((svg_info->bounds.x != 0.0) || (svg_info->bounds.y != 0.0))
(void) FormatLocaleFile(svg_info->file,"translate %g,%g\n",
svg_info->bounds.x,svg_info->bounds.y);
- text=EscapeString(svg_info->url,'\"');
- (void) FormatLocaleFile(svg_info->file,"use \"url(%s)\"\n",text);
- text=DestroyString(text);
+ (void) FormatLocaleFile(svg_info->file,"use \"url(%s)\"\n",
+ svg_info->url);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
break;
}
@@ -2937,12 +2942,8 @@ static void SVGEndElement(void *context,const xmlChar *name)
static void SVGCharacters(void *context,const xmlChar *c,int length)
{
char
- *p,
*text;
- ssize_t
- i;
-
SVGInfo
*svg_info;
@@ -2959,10 +2960,8 @@ static void SVGCharacters(void *context,const xmlChar *c,int length)
text=(char *) AcquireQuantumMemory((size_t) length+1,sizeof(*text));
if (text == (char *) NULL)
return;
- p=text;
- for (i=0; i < (ssize_t) length; i++)
- *p++=(char) c[i];
- *p='\0';
+ memcpy(text,c,length);
+ text[length] = '\0';
SVGStripString(MagickFalse,text);
if (svg_info->text == (char *) NULL)
svg_info->text=text;