Fix for #178
- make sure nsvg__addPath() hands only valid number of pointts (1+N*3) - require moveTo path command before handling other commands - require (sign+)digit for a valid path command coordinate - allow to add bezier segment only after there’s at leat one point (now also consistent with nsvg__lineTo)
This commit is contained in:
parent
07a5e2a33c
commit
e7f5981b1e
@ -225,11 +225,6 @@ static int nsvg__isdigit(char c)
|
|||||||
return c >= '0' && c <= '9';
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nsvg__isnum(char c)
|
|
||||||
{
|
|
||||||
return strchr("0123456789+-.eE", c) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
|
static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
|
||||||
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
|
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
|
||||||
|
|
||||||
@ -736,9 +731,11 @@ static void nsvg__lineTo(NSVGparser* p, float x, float y)
|
|||||||
|
|
||||||
static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
|
static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
|
||||||
{
|
{
|
||||||
nsvg__addPoint(p, cpx1, cpy1);
|
if (p->npts > 0) {
|
||||||
nsvg__addPoint(p, cpx2, cpy2);
|
nsvg__addPoint(p, cpx1, cpy1);
|
||||||
nsvg__addPoint(p, x, y);
|
nsvg__addPoint(p, cpx2, cpy2);
|
||||||
|
nsvg__addPoint(p, x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSVGattrib* nsvg__getAttr(NSVGparser* p)
|
static NSVGattrib* nsvg__getAttr(NSVGparser* p)
|
||||||
@ -1040,6 +1037,10 @@ static void nsvg__addPath(NSVGparser* p, char closed)
|
|||||||
if (closed)
|
if (closed)
|
||||||
nsvg__lineTo(p, p->pts[0], p->pts[1]);
|
nsvg__lineTo(p, p->pts[0], p->pts[1]);
|
||||||
|
|
||||||
|
// Expect 1 + N*3 points (N = number of cubic bezier segments).
|
||||||
|
if ((p->npts % 3) != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
path = (NSVGpath*)malloc(sizeof(NSVGpath));
|
path = (NSVGpath*)malloc(sizeof(NSVGpath));
|
||||||
if (path == NULL) goto error;
|
if (path == NULL) goto error;
|
||||||
memset(path, 0, sizeof(NSVGpath));
|
memset(path, 0, sizeof(NSVGpath));
|
||||||
@ -1458,6 +1459,15 @@ static int nsvg__parseUnits(const char* units)
|
|||||||
return NSVG_UNITS_USER;
|
return NSVG_UNITS_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nsvg__isCoordinate(const char* s)
|
||||||
|
{
|
||||||
|
// optional sign
|
||||||
|
if (*s == '-' || *s == '+')
|
||||||
|
s++;
|
||||||
|
// must have at least one digit
|
||||||
|
return nsvg__isdigit(*s);
|
||||||
|
}
|
||||||
|
|
||||||
static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
|
static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
|
||||||
{
|
{
|
||||||
NSVGcoordinate coord = {0, NSVG_UNITS_USER};
|
NSVGcoordinate coord = {0, NSVG_UNITS_USER};
|
||||||
@ -1883,8 +1893,11 @@ static int nsvg__getArgsPerElement(char cmd)
|
|||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
return 7;
|
return 7;
|
||||||
|
case 'z':
|
||||||
|
case 'Z':
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
|
static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
|
||||||
@ -2194,6 +2207,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
float args[10];
|
float args[10];
|
||||||
int nargs;
|
int nargs;
|
||||||
int rargs = 0;
|
int rargs = 0;
|
||||||
|
char initPoint;
|
||||||
float cpx, cpy, cpx2, cpy2;
|
float cpx, cpy, cpx2, cpy2;
|
||||||
const char* tmp[4];
|
const char* tmp[4];
|
||||||
char closedFlag;
|
char closedFlag;
|
||||||
@ -2216,13 +2230,14 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
nsvg__resetPath(p);
|
nsvg__resetPath(p);
|
||||||
cpx = 0; cpy = 0;
|
cpx = 0; cpy = 0;
|
||||||
cpx2 = 0; cpy2 = 0;
|
cpx2 = 0; cpy2 = 0;
|
||||||
|
initPoint = 0;
|
||||||
closedFlag = 0;
|
closedFlag = 0;
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
s = nsvg__getNextPathItem(s, item);
|
s = nsvg__getNextPathItem(s, item);
|
||||||
if (!*item) break;
|
if (!*item) break;
|
||||||
if (nsvg__isnum(item[0])) {
|
if (cmd != '\0' && nsvg__isCoordinate(item)) {
|
||||||
if (nargs < 10)
|
if (nargs < 10)
|
||||||
args[nargs++] = (float)nsvg__atof(item);
|
args[nargs++] = (float)nsvg__atof(item);
|
||||||
if (nargs >= rargs) {
|
if (nargs >= rargs) {
|
||||||
@ -2235,6 +2250,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
cmd = (cmd == 'm') ? 'l' : 'L';
|
cmd = (cmd == 'm') ? 'l' : 'L';
|
||||||
rargs = nsvg__getArgsPerElement(cmd);
|
rargs = nsvg__getArgsPerElement(cmd);
|
||||||
cpx2 = cpx; cpy2 = cpy;
|
cpx2 = cpx; cpy2 = cpy;
|
||||||
|
initPoint = 1;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'L':
|
case 'L':
|
||||||
@ -2284,7 +2300,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd = item[0];
|
cmd = item[0];
|
||||||
rargs = nsvg__getArgsPerElement(cmd);
|
|
||||||
if (cmd == 'M' || cmd == 'm') {
|
if (cmd == 'M' || cmd == 'm') {
|
||||||
// Commit path.
|
// Commit path.
|
||||||
if (p->npts > 0)
|
if (p->npts > 0)
|
||||||
@ -2293,7 +2308,11 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
nsvg__resetPath(p);
|
nsvg__resetPath(p);
|
||||||
closedFlag = 0;
|
closedFlag = 0;
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
} else if (cmd == 'Z' || cmd == 'z') {
|
} else if (initPoint == 0) {
|
||||||
|
// Do not allow other commands until initial point has been set (moveTo called once).
|
||||||
|
cmd = '\0';
|
||||||
|
}
|
||||||
|
if (cmd == 'Z' || cmd == 'z') {
|
||||||
closedFlag = 1;
|
closedFlag = 1;
|
||||||
// Commit path.
|
// Commit path.
|
||||||
if (p->npts > 0) {
|
if (p->npts > 0) {
|
||||||
@ -2309,6 +2328,12 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
|
|||||||
closedFlag = 0;
|
closedFlag = 0;
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
}
|
}
|
||||||
|
rargs = nsvg__getArgsPerElement(cmd);
|
||||||
|
if (rargs == -1) {
|
||||||
|
// Command not recognized
|
||||||
|
cmd = '\0';
|
||||||
|
rargs = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Commit path.
|
// Commit path.
|
||||||
|
Loading…
Reference in New Issue
Block a user