File ImageMagick-CVE-2016-4562,4563,4564.patch of Package ImageMagick

m 2d009ebb22bcc8865e2ffecf5764ac4f1599a647 Mon Sep 17 00:00:00 2001
From: Cristy <urban-warrior@imagemagick.org>
Date: Wed, 4 May 2016 19:08:19 -0400
Subject: [PATCH] Prevent buffer overflow in magick/draw.c

Index: ImageMagick-6.8.9-8/magick/draw.c
===================================================================
--- ImageMagick-6.8.9-8.orig/magick/draw.c	2014-05-01 02:42:05.000000000 +0200
+++ ImageMagick-6.8.9-8/magick/draw.c	2016-06-08 09:01:46.292651843 +0200
@@ -1584,7 +1584,7 @@ static MagickBooleanType DrawDashPolygon
   status=MagickTrue;
   maximum_length=0.0;
   total_length=0.0;
-  for (i=1; i < (ssize_t) number_vertices; i++)
+  for (i=1; (i < (ssize_t) number_vertices) && (length >= 0.0); i++)
   {
     dx=primitive_info[i].point.x-primitive_info[i-1].point.x;
     dy=primitive_info[i].point.y-primitive_info[i-1].point.y;
@@ -1701,6 +1701,135 @@ static inline void TracePoint(PrimitiveI
   primitive_info->point=point;
 }
 
+static void GetNextToken(const char *start,const char **end,
+  const size_t extent,char *token)
+{
+  double
+    value;
+
+  register const char
+    *p;
+
+  register ssize_t
+    i;
+
+  assert(start != (const char *) NULL);
+  assert(token != (char *) NULL);
+  i=0;
+  p=start;
+  while ((isspace((int) ((unsigned char) *p)) != 0) && (*p != '\0'))
+    p++;
+  switch (*p)
+  {
+    case '\0':
+      break;
+    case '"':
+    case '\'':
+    case '`':
+    case '{':
+    {
+      register char
+        escape;
+
+      switch (*p)
+      {
+        case '"': escape='"'; break;
+        case '\'': escape='\''; break;
+        case '`': escape='\''; break;
+        case '{': escape='}'; break;
+        default: escape=(*p); break;
+      }
+      for (p++; *p != '\0'; p++)
+      {
+        if ((*p == '\\') && ((*(p+1) == escape) || (*(p+1) == '\\')))
+          p++;
+        else
+          if (*p == escape)
+            {
+              p++;
+              break;
+            }
+        if (i < (ssize_t) (extent-1))
+          token[i++]=(*p);
+      }
+      break;
+    }
+    case '/':
+    {
+      if (i < (ssize_t) (extent-1))
+        token[i++]=(*p++);
+      if ((*p == '>') || (*p == '/'))
+        if (i < (ssize_t) (extent-1))
+          token[i++]=(*p++);
+      break;
+    }
+    default:
+    {
+      char
+        *q;
+
+      value=StringToDouble(p,&q);
+      (void) value;
+      if ((p != q) && (*p != ','))
+        {
+          for ( ; (p < q) && (*p != ','); p++)
+            if (i < (ssize_t) (extent-1))
+              token[i++]=(*p);
+          if (*p == '%')
+            if (i < (ssize_t) (extent-1))
+              token[i++]=(*p++);
+          break;
+        }
+      if ((*p != '\0') && (isalpha((int) ((unsigned char) *p)) == 0) &&
+          (*p != *DirectorySeparator) && (*p != '#') && (*p != '<'))
+        {
+          if (i < (ssize_t) (extent-1))
+            token[i++]=(*p++);
+          break;
+        }
+      for ( ; *p != '\0'; p++)
+      {
+        if (((isspace((int) ((unsigned char) *p)) != 0) || (*p == '=') ||
+            (*p == ',') || (*p == ':') || (*p == ';')) && (*(p-1) != '\\'))
+          break;
+        if ((i > 0) && (*p == '<'))
+          break;
+        if (i < (ssize_t) (extent-1))
+          token[i++]=(*p);
+        if (*p == '>')
+          break;
+        if (*p == '(')
+          for (p++; *p != '\0'; p++)
+          {
+            if (i < (ssize_t) (extent-1))
+              token[i++]=(*p);
+            if ((*p == ')') && (*(p-1) != '\\'))
+              break;
+          }
+      }
+      break;
+    }
+  }
+  token[i]='\0';
+  if (LocaleNCompare(token,"url(",4) == 0)
+    {
+      ssize_t
+        offset;
+
+      offset=4;
+      if (token[offset] == '#')
+        offset++;
+      i=(ssize_t) strlen(token);
+      (void) CopyMagickString(token,token+offset,MaxTextExtent);
+      token[i-offset-1]='\0';
+    }
+  while (isspace((int) ((unsigned char) *p)) != 0)
+    p++;
+  if (end != (const char **) NULL)
+    *end=(const char *) p;
+}
+
+
 MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
 {
 #define RenderImageTag  "Render/Image"
@@ -1831,7 +1960,7 @@ MagickExport MagickBooleanType DrawImage
     /*
       Interpret graphic primitive.
     */
-    GetMagickToken(q,&q,keyword);
+    GetNextToken(q,&q,MaxTextExtent,keyword);
     if (*keyword == '\0')
       break;
     if (*keyword == '#')
@@ -2135,7 +2264,7 @@ MagickExport MagickBooleanType DrawImage
         if (LocaleCompare("font-weight",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->weight=StringToUnsignedLong(token);
+            graphic_context[n]->weight=(ssize_t) StringToUnsignedLong(token);
             if (LocaleCompare(token,"all") == 0)
               graphic_context[n]->weight=0;
             if (LocaleCompare(token,"bold") == 0)
@@ -5985,17 +6114,29 @@ static PrimitiveInfo *TraceStrokePolygon
       }
     if (q >= (ssize_t) (max_strokes-6*BezierQuantum-360))
       {
-         max_strokes+=6*BezierQuantum+360;
-         path_p=(PointInfo *) ResizeQuantumMemory(path_p,(size_t) max_strokes,
-           sizeof(*path_p));
-         path_q=(PointInfo *) ResizeQuantumMemory(path_q,(size_t) max_strokes,
-           sizeof(*path_q));
-         if ((path_p == (PointInfo *) NULL) || (path_q == (PointInfo *) NULL))
-           {
-             polygon_primitive=(PrimitiveInfo *)
-               RelinquishMagickMemory(polygon_primitive);
-             return((PrimitiveInfo *) NULL);
-           }
+        if (~max_strokes < (6*BezierQuantum+360))
+          {
+            path_p=(PointInfo *) RelinquishMagickMemory(path_p);
+            path_q=(PointInfo *) RelinquishMagickMemory(path_q);
+          }
+        else
+          {
+            max_strokes+=6*BezierQuantum+360;
+            path_p=(PointInfo *) ResizeQuantumMemory(path_p,max_strokes,
+              sizeof(*path_p));
+            path_q=(PointInfo *) ResizeQuantumMemory(path_q,max_strokes,
+              sizeof(*path_q));
+          }
+        if ((path_p == (PointInfo *) NULL) || (path_q == (PointInfo *) NULL))
+          {
+            if (path_p != (PointInfo *) NULL)
+              path_p=(PointInfo *) RelinquishMagickMemory(path_p);
+            if (path_q != (PointInfo *) NULL)
+              path_q=(PointInfo *) RelinquishMagickMemory(path_q);
+            polygon_primitive=(PrimitiveInfo *)
+              RelinquishMagickMemory(polygon_primitive);
+            return((PrimitiveInfo *) NULL);
+          }
       }
     dot_product=dx.q*dy.p-dx.p*dy.q;
     if (dot_product <= 0.0)
@@ -6057,7 +6198,7 @@ static PrimitiveInfo *TraceStrokePolygon
           q++;
           for (j=1; j < (ssize_t) arc_segments; j++)
           {
-            delta_theta=(j*(theta.q-theta.p)/arc_segments);
+            delta_theta=(double) (j*(theta.q-theta.p)/arc_segments);
             path_q[q].x=(double) (center.x+mid*cos(fmod((double)
               (theta.p+delta_theta),DegreesToRadians(360.0))));
             path_q[q].y=(double) (center.y+mid*sin(fmod((double)
@@ -6127,7 +6268,7 @@ static PrimitiveInfo *TraceStrokePolygon
           path_p[p++]=box_p[1];
           for (j=1; j < (ssize_t) arc_segments; j++)
           {
-            delta_theta=(j*(theta.q-theta.p)/arc_segments);
+            delta_theta=(double) (j*(theta.q-theta.p)/arc_segments);
             path_p[p].x=(double) (center.x+mid*cos(fmod((double)
               (theta.p+delta_theta),DegreesToRadians(360.0))));
             path_p[p].y=(double) (center.y+mid*sin(fmod((double)
openSUSE Build Service is sponsored by