# HG changeset patch
# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
# Date 1502890099 18000
# Node ID 54f48ab2d52a2a4af99781057075d8ea9744a649
# Parent  4970ea920a9388d6f08be1b35d58ef5efded4908
SVG: Fix buffer-overflow and inconsistent behavior in GetStyleTokens().

diff -r 4970ea920a93 -r 54f48ab2d52a coders/svg.c
--- a/coders/svg.c	Tue Aug 15 08:05:00 2017 -0500
+++ b/coders/svg.c	Wed Aug 16 08:28:19 2017 -0500
@@ -267,11 +267,12 @@
   char
     **tokens;
 
-  register const char
+  const char
     *p,
     *q;
 
-  register size_t
+  size_t
+    alloc_tokens,
     i;
 
   SVGInfo
@@ -279,21 +280,27 @@
 
   svg_info=(SVGInfo *) context;
   *number_tokens=0;
+  alloc_tokens=0;
   if (text == (const char *) NULL)
     return((char **) NULL);
   /*
     Determine the number of arguments.
+
+    style="fill: red; stroke: blue; stroke-width: 3"
   */
   for (p=text; *p != '\0'; p++)
     if (*p == ':')
-      (*number_tokens)+=2;
-  tokens=MagickAllocateMemory(char **,(*number_tokens+2)*sizeof(*tokens));
+      alloc_tokens+=2;
+  if (alloc_tokens == 0)
+    return((char **) NULL);
+  tokens=MagickAllocateMemory(char **,(alloc_tokens+2)*sizeof(*tokens));
   if (tokens == (char **) NULL)
     {
       ThrowException3(svg_info->exception,ResourceLimitError,
                       MemoryAllocationFailed,UnableToConvertStringToTokens);
       return((char **) NULL);
     }
+  (void) memset(tokens,0,(alloc_tokens+2)*sizeof(*tokens));
   /*
     Convert string to an ASCII list.
   */
@@ -304,14 +311,36 @@
       if ((*q != ':') && (*q != ';') && (*q != '\0'))
         continue;
       tokens[i]=AllocateString(p);
+      if (tokens[i] == NULL)
+        {
+          ThrowException3(svg_info->exception,ResourceLimitError,
+                          MemoryAllocationFailed,UnableToConvertStringToTokens);
+          break;
+        }
       (void) strlcpy(tokens[i],p,q-p+1);
-      Strip(tokens[i++]);
+      Strip(tokens[i]);
+      i++;
+      if (i >= alloc_tokens)
+        break;
       p=q+1;
     }
-  tokens[i]=AllocateString(p);
-  (void) strlcpy(tokens[i],p,q-p+1);
-  Strip(tokens[i++]);
+  if (i < alloc_tokens)
+    {
+      tokens[i]=AllocateString(p);
+      if (tokens[i] == NULL)
+        {
+          ThrowException3(svg_info->exception,ResourceLimitError,
+                          MemoryAllocationFailed,UnableToConvertStringToTokens);
+        }
+      else
+        {
+          (void) strlcpy(tokens[i],p,q-p+1);
+          Strip(tokens[i]);
+          i++;
+        }
+    }
   tokens[i]=(char *) NULL;
+  *number_tokens=i;
   return(tokens);
 }
 
