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)