# HG changeset patch # User Bob Friesenhahn # 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); }