Commit 335aadb09 for imagemagick.org

commit 335aadb0923c43b4776ad293732d78b584fa0611
Author: Cristy <urban-warrior@imagemagick.org>
Date:   Fri Jun 5 20:03:20 2026 -0400

    https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-vgh5-r42g-4j44

diff --git a/MagickCore/draw.c b/MagickCore/draw.c
index 4cd7ac548..5e96d10f1 100644
--- a/MagickCore/draw.c
+++ b/MagickCore/draw.c
@@ -2460,7 +2460,28 @@ static SplayTreeInfo *GetMVGMacros(const char *primitive)
   return(macros);
 }

-static inline MagickBooleanType IsPoint(const char *point)
+static inline MagickBooleanType IsValidListChar(int c)
+{
+  if ((c >= '0') && (c <= '9'))
+    return(MagickTrue);
+  switch (c)
+  {
+    case '.':
+    case '+':
+    case '-':
+    case ',':
+    case ' ':
+    case '\t':
+    case '\r':
+    case '\n':
+      break;
+    default:
+      return(MagickFalse);
+  }
+  return(MagickTrue);
+}
+
+static inline MagickBooleanType IsValidPoint(const char *point)
 {
   char
     *p;
@@ -2673,30 +2694,40 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.ry=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.rx=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.sy=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.tx=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.ty=GetDrawValue(token,&next_token);
@@ -3182,7 +3213,7 @@ static MagickBooleanType RenderMVGContent(Image *image,
         if (LocaleCompare("letter-spacing",keyword) == 0)
           {
             (void) GetNextToken(q,&q,extent,token);
-            if (IsPoint(token) == MagickFalse)
+            if (IsValidPoint(token) == MagickFalse)
               break;
             clone_info=CloneDrawInfo((ImageInfo *) NULL,graphic_context[n]);
             clone_info->text=AcquireString(" ");
@@ -3266,7 +3297,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (graphic_context[n]->fill.alpha != (double) TransparentAlpha)
               {
                 graphic_context[n]->fill.alpha=graphic_context[n]->fill_alpha;
-                graphic_context[n]->stroke.alpha=graphic_context[n]->stroke_alpha;
+                graphic_context[n]->stroke.alpha=
+                  graphic_context[n]->stroke_alpha;
               }
             else
               {
@@ -3427,18 +3459,24 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 segment.y1=GetDrawValue(token,&next_token);
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 segment.x2=GetDrawValue(token,&next_token);
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 segment.y2=GetDrawValue(token,&next_token);
@@ -3447,6 +3485,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 if (LocaleCompare(type,"radial") == 0)
                   {
                     (void) GetNextToken(q,&q,extent,token);
+                    if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                      ThrowPointExpectedException(token,exception);
                     if (*token == ',')
                       (void) GetNextToken(q,&q,extent,token);
                   }
@@ -3547,6 +3587,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 region.y=CastDoubleToSsizeT(ceil(GetDrawValue(token,
@@ -3554,6 +3596,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 region.width=CastDoubleToSizeT(floor(GetDrawValue(token,
@@ -3561,6 +3605,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 if (token == next_token)
                   ThrowPointExpectedException(token,exception);
                 (void) GetNextToken(q,&q,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(q,&q,extent,token);
                 region.height=CastDoubleToSizeT(GetDrawValue(token,
@@ -3647,6 +3693,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.sy=GetDrawValue(token,&next_token);
@@ -3745,18 +3793,22 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (graphic_context[n]->dash_pattern != (double *) NULL)
               graphic_context[n]->dash_pattern=(double *)
                 RelinquishMagickMemory(graphic_context[n]->dash_pattern);
-            if (IsPoint(q) != MagickFalse)
+            if (IsValidPoint(q) != MagickFalse)
               {
                 const char
                   *r;

                 r=q;
                 (void) GetNextToken(r,&r,extent,token);
+                if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                  ThrowPointExpectedException(token,exception);
                 if (*token == ',')
                   (void) GetNextToken(r,&r,extent,token);
-                for (x=0; IsPoint(token) != MagickFalse; x++)
+                for (x=0; IsValidPoint(token) != MagickFalse; x++)
                 {
                   (void) GetNextToken(r,&r,extent,token);
+                  if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                    ThrowPointExpectedException(token,exception);
                   if (*token == ',')
                     (void) GetNextToken(r,&r,extent,token);
                 }
@@ -3776,6 +3828,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
                 for (j=0; j < x; j++)
                 {
                   (void) GetNextToken(q,&q,extent,token);
+                  if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+                    ThrowPointExpectedException(token,exception);
                   if (*token == ',')
                     (void) GetNextToken(q,&q,extent,token);
                   graphic_context[n]->dash_pattern[j]=GetDrawValue(token,
@@ -3939,6 +3993,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             affine.ty=GetDrawValue(token,&next_token);
@@ -3986,6 +4042,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             graphic_context[n]->viewbox.y=CastDoubleToSsizeT(
@@ -3993,6 +4051,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             graphic_context[n]->viewbox.width=CastDoubleToSizeT(floor(
@@ -4000,6 +4060,8 @@ static MagickBooleanType RenderMVGContent(Image *image,
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(q,&q,extent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(q,&q,extent,token);
             graphic_context[n]->viewbox.height=CastDoubleToSizeT(floor(
@@ -4091,13 +4153,15 @@ static MagickBooleanType RenderMVGContent(Image *image,
       /*
         Define points.
       */
-      if (IsPoint(q) == MagickFalse)
+      if (IsValidPoint(q) == MagickFalse)
         break;
       (void) GetNextToken(q,&q,extent,token);
       point.x=GetDrawValue(token,&next_token);
       if (token == next_token)
         ThrowPointExpectedException(token,exception);
       (void) GetNextToken(q,&q,extent,token);
+      if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+        ThrowPointExpectedException(token,exception);
       if (*token == ',')
         (void) GetNextToken(q,&q,extent,token);
       point.y=GetDrawValue(token,&next_token);
@@ -6707,40 +6771,56 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
         do
         {
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           arc.x=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           arc.y=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           angle=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           large_arc=StringToLong(token) != 0 ? MagickTrue : MagickFalse;
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           sweep=StringToLong(token) != 0 ? MagickTrue : MagickFalse;
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           x=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           y=GetDrawValue(token,&next_token);
@@ -6758,7 +6838,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'c':
@@ -6773,12 +6853,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
           for (i=1; i < 4; i++)
           {
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             x=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             y=GetDrawValue(token,&next_token);
@@ -6800,7 +6884,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'H':
@@ -6809,6 +6893,8 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
         do
         {
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           x=GetDrawValue(token,&next_token);
@@ -6826,7 +6912,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'l':
@@ -6838,12 +6924,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
         do
         {
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           x=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           y=GetDrawValue(token,&next_token);
@@ -6862,7 +6952,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'M':
@@ -6883,12 +6973,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
         do
         {
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           x=GetDrawValue(token,&next_token);
           if (token == next_token)
             ThrowPointExpectedException(token,exception);
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           y=GetDrawValue(token,&next_token);
@@ -6910,7 +7004,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'q':
@@ -6925,12 +7019,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
           for (i=1; i < 3; i++)
           {
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             x=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             y=GetDrawValue(token,&next_token);
@@ -6954,7 +7052,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 's':
@@ -6971,12 +7069,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
           for (i=2; i < 4; i++)
           {
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             x=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             y=GetDrawValue(token,&next_token);
@@ -7006,7 +7108,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 't':
@@ -7023,12 +7125,16 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
           for (i=2; i < 3; i++)
           {
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             x=GetDrawValue(token,&next_token);
             if (token == next_token)
               ThrowPointExpectedException(token,exception);
             (void) GetNextToken(p,&p,MagickPathExtent,token);
+            if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+              ThrowPointExpectedException(token,exception);
             if (*token == ',')
               (void) GetNextToken(p,&p,MagickPathExtent,token);
             y=GetDrawValue(token,&next_token);
@@ -7058,7 +7164,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'v':
@@ -7070,6 +7176,8 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
         do
         {
           (void) GetNextToken(p,&p,MagickPathExtent,token);
+          if (IsValidListChar((int) ((unsigned char) *token)) == MagickFalse)
+            ThrowPointExpectedException(token,exception);
           if (*token == ',')
             (void) GetNextToken(p,&p,MagickPathExtent,token);
           y=GetDrawValue(token,&next_token);
@@ -7087,7 +7195,7 @@ static ssize_t TracePath(MVGInfo *mvg_info,const char *path,
             p++;
           if (*p == ',')
             p++;
-        } while (IsPoint(p) != MagickFalse);
+        } while (IsValidPoint(p) != MagickFalse);
         break;
       }
       case 'z':