diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2021-02-22 14:36:44 +0100 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2021-02-22 14:37:26 +0100 |
| commit | 9f84fd05e8090c3b7554c965d15ac5c41a0d4852 (patch) | |
| tree | 3c7b0ff3358b004a26c5fe5a390d250734e84e3a | |
| parent | 28aaa4d4ce6e7c766995c1d2dca9ac6b3c82b6b7 (diff) | |
Update bundled nanosvg library to latest version
For details see:
- README.bundled-libs.txt
- nanosvg/README.txt
| -rw-r--r-- | README.bundled-libs.txt | 10 | ||||
| -rw-r--r-- | nanosvg/README.txt | 42 | ||||
| -rw-r--r-- | nanosvg/nanosvg.h | 122 |
3 files changed, 126 insertions, 48 deletions
diff --git a/README.bundled-libs.txt b/README.bundled-libs.txt index f1cb3a766..92bfb0b3c 100644 --- a/README.bundled-libs.txt +++ b/README.bundled-libs.txt @@ -17,7 +17,7 @@ Current versions of bundled libraries: Library Version Release date FLTK Version -------------------------------------------------------------------------- jpeg jpeg-9c 2018-01-14 1.4.0 - nanosvg f31098fa85 [1] 2019-05-23 1.4.0 + nanosvg a1eea27b3d [1] 2021-02-21 1.4.0 png libpng-1.6.37 2019-04-14 1.4.0 zlib zlib-1.2.11 2017-01-15 1.4.0 @@ -25,13 +25,14 @@ Previous versions of bundled libraries: Library Version Release date FLTK Version ------------------------------------------------------------------ - nanosvg ce81a6577c [1] 2018-07-01 1.4.0 + nanosvg f31098fa85 [1] 2019-05-23 1.4.x jpeg jpeg-9a 2014-01-19 1.3.5 png libpng-1.6.16 2014-12-22 1.3.5 zlib zlib-1.2.8 2013-04-28 1.3.5 [1] Git commit in: https://github.com/fltk/nanosvg - See also git tag 'fltk_yyyy-mm-dd' where yyyy-mm-dd == "Release date". + See also git tag 'fltk_yyyy-mm-dd' where yyyy-mm-dd == "Release date" + and file nanosvg/README.txt. General information: @@ -191,6 +192,9 @@ nanosvg: so we no longer need our own patches. AlbrechtS, 04 Feb 2018. + Update (Feb 22, 2021): The upstream library is officially no longer + maintained (see README.md) although updates appear from time to time. + Use this clone (branch 'fltk') to get the nanosvg library with FLTK specific patches: diff --git a/nanosvg/README.txt b/nanosvg/README.txt index 2cb5de3f4..7bea79582 100644 --- a/nanosvg/README.txt +++ b/nanosvg/README.txt @@ -11,9 +11,49 @@ The original library can be found here: https://github.com/memononen/nanosvg -The modified library was cloned and can be found here: +The modified library was forked and can be found here: https://github.com/fltk/nanosvg For more information see README.bundled-libs.txt in FLTK's root directory. + + +Changes in the FLTK fork, branch 'fltk': +----------------------------------------- + +$ git show --no-patch fltk_2021-02-22 +tag fltk_2021-02-22 +Tagger: Albrecht Schlosser <...> +Date: Mon Feb 22 14:16:58 2021 +0100 + +Included in FLTK 1.4.x as of Feb 22, 2021 + +Latest upstream changes: +------------------------ + +commit 3e403ec72a9145cbbcc6c63d94a4caf079aafec2 +Merge: cc6c08d 45eb9f8 +Author: Mikko Mononen <...> +Date: Fri Nov 20 12:53:11 2020 +0200 + + Merge pull request #189 from fvogelnew1/Fix-for-#188 + + Update nanosvg.h + +Changes in branch 'fltk': + + $ git shortlog master..fltk + + AlbrechtS (2): + Fix Visual Studio compilation error (missing long long). + Modify rasterizer to support non-square X,Y axes scaling. + + Greg Ercolano (1): + Address crash defined in fltk's issue 180 + +commit a1eea27b3db2d15d924ea823dd0acc5bd2aa56f1 +Author: Greg Ercolano <...> +Date: Mon Jan 18 15:05:13 2021 -0800 + + Address crash defined in fltk's issue 180 diff --git a/nanosvg/nanosvg.h b/nanosvg/nanosvg.h index cfff38f89..035b0e52e 100644 --- a/nanosvg/nanosvg.h +++ b/nanosvg/nanosvg.h @@ -225,11 +225,6 @@ static int nsvg__isdigit(char c) 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__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) { - nsvg__addPoint(p, cpx1, cpy1); - nsvg__addPoint(p, cpx2, cpy2); - nsvg__addPoint(p, x, y); + if (p->npts > 0) { + nsvg__addPoint(p, cpx1, cpy1); + nsvg__addPoint(p, cpx2, cpy2); + nsvg__addPoint(p, x, y); + } } static NSVGattrib* nsvg__getAttr(NSVGparser* p) @@ -808,7 +805,9 @@ static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) { NSVGgradientData* grad = p->gradients; - while (grad) { + if (id == NULL || *id == '\0') + return NULL; + while (grad != NULL) { if (strcmp(grad->id, id) == 0) return grad; grad = grad->next; @@ -825,19 +824,26 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const f NSVGgradient* grad; float ox, oy, sw, sh, sl; int nstops = 0; + int refIter; data = nsvg__findGradientData(p, id); if (data == NULL) return NULL; // TODO: use ref to fill in all unset values too. ref = data; + refIter = 0; while (ref != NULL) { + NSVGgradientData* nextRef = NULL; if (stops == NULL && ref->stops != NULL) { stops = ref->stops; nstops = ref->nstops; break; } - ref = nsvg__findGradientData(p, ref->ref); + nextRef = nsvg__findGradientData(p, ref->ref); + if (nextRef == ref) break; // prevent infite loops on malformed data + ref = nextRef; + refIter++; + if (refIter > 32) break; // prevent infite loops on malformed data } if (stops == NULL) return NULL; @@ -1040,6 +1046,10 @@ static void nsvg__addPath(NSVGparser* p, char closed) if (closed) 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)); if (path == NULL) goto error; memset(path, 0, sizeof(NSVGpath)); @@ -1213,35 +1223,28 @@ static const char* nsvg__getNextPathItem(const char* s, char* it) static unsigned int nsvg__parseColorHex(const char* str) { - unsigned int c = 0, r = 0, g = 0, b = 0; - int n = 0; - str++; // skip # - // Calculate number of characters. - while(str[n] && !nsvg__isspace(str[n])) - n++; - if (n == 6) { - sscanf(str, "%x", &c); - } else if (n == 3) { - sscanf(str, "%x", &c); - c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8); - c |= c<<4; - } - r = (c >> 16) & 0xff; - g = (c >> 8) & 0xff; - b = c & 0xff; - return NSVG_RGB(r,g,b); + // FLTK: Solve fltk issue#180 / CVE-2019-1000032 + unsigned int r=0, g=0, b=0; + if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex + return NSVG_RGB(r, g, b); + if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa + return NSVG_RGB(r*17, g*17, b*17); // has same effect as (r<<4|r), (g<<4|g), .. + return NSVG_RGB(128, 128, 128); } static unsigned int nsvg__parseColorRGB(const char* str) { - int r = -1, g = -1, b = -1; - char s1[32]="", s2[32]=""; - sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b); - if (strchr(s1, '%')) { - return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100); - } else { - return NSVG_RGB(r,g,b); + // FLTK: Solve fltk issue#180 / CVE-2019-1000032 + unsigned int r=0, g=0, b=0; + if (sscanf(str, "rgb(%u, %u, %u)", &r, &g, &b) == 3) // decimal integers + return NSVG_RGB(r, g, b); + if (sscanf(str, "rgb(%u%%, %u%%, %u%%)", &r, &g, &b) == 3) { // decimal integer percentage + r = (r <= 100) ? ((r*255)/100) : 255; // clip percentages >100 + g = (g <= 100) ? ((g*255)/100) : 255; + b = (b <= 100) ? ((b*255)/100) : 255; + return NSVG_RGB(r, g, b); } + return NSVG_RGB(128, 128, 128); } typedef struct NSVGNamedColor { @@ -1466,6 +1469,15 @@ static int nsvg__parseUnits(const char* units) return NSVG_UNITS_USER; } +static int nsvg__isCoordinate(const char* s) +{ + // optional sign + if (*s == '-' || *s == '+') + s++; + // must have at least one digit, or start by a dot + return (nsvg__isdigit(*s) || *s == '.'); +} + static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) { NSVGcoordinate coord = {0, NSVG_UNITS_USER}; @@ -1605,25 +1617,32 @@ static int nsvg__parseRotate(float* xform, const char* str) static void nsvg__parseTransform(float* xform, const char* str) { float t[6]; + int len; nsvg__xformIdentity(xform); while (*str) { if (strncmp(str, "matrix", 6) == 0) - str += nsvg__parseMatrix(t, str); + len = nsvg__parseMatrix(t, str); else if (strncmp(str, "translate", 9) == 0) - str += nsvg__parseTranslate(t, str); + len = nsvg__parseTranslate(t, str); else if (strncmp(str, "scale", 5) == 0) - str += nsvg__parseScale(t, str); + len = nsvg__parseScale(t, str); else if (strncmp(str, "rotate", 6) == 0) - str += nsvg__parseRotate(t, str); + len = nsvg__parseRotate(t, str); else if (strncmp(str, "skewX", 5) == 0) - str += nsvg__parseSkewX(t, str); + len = nsvg__parseSkewX(t, str); else if (strncmp(str, "skewY", 5) == 0) - str += nsvg__parseSkewY(t, str); + len = nsvg__parseSkewY(t, str); else{ ++str; continue; } + if (len != 0) { + str += len; + } else { + ++str; + continue; + } nsvg__xformPremultiply(xform, t); } @@ -1884,8 +1903,11 @@ static int nsvg__getArgsPerElement(char cmd) case 'a': case 'A': 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) @@ -2195,6 +2217,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) float args[10]; int nargs; int rargs = 0; + char initPoint; float cpx, cpy, cpx2, cpy2; const char* tmp[4]; char closedFlag; @@ -2217,13 +2240,14 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) nsvg__resetPath(p); cpx = 0; cpy = 0; cpx2 = 0; cpy2 = 0; + initPoint = 0; closedFlag = 0; nargs = 0; while (*s) { s = nsvg__getNextPathItem(s, item); if (!*item) break; - if (nsvg__isnum(item[0])) { + if (cmd != '\0' && nsvg__isCoordinate(item)) { if (nargs < 10) args[nargs++] = (float)nsvg__atof(item); if (nargs >= rargs) { @@ -2236,6 +2260,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) cmd = (cmd == 'm') ? 'l' : 'L'; rargs = nsvg__getArgsPerElement(cmd); cpx2 = cpx; cpy2 = cpy; + initPoint = 1; break; case 'l': case 'L': @@ -2285,7 +2310,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) } } else { cmd = item[0]; - rargs = nsvg__getArgsPerElement(cmd); if (cmd == 'M' || cmd == 'm') { // Commit path. if (p->npts > 0) @@ -2294,7 +2318,11 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) nsvg__resetPath(p); closedFlag = 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; // Commit path. if (p->npts > 0) { @@ -2310,6 +2338,12 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr) closedFlag = 0; nargs = 0; } + rargs = nsvg__getArgsPerElement(cmd); + if (rargs == -1) { + // Command not recognized + cmd = '\0'; + rargs = 0; + } } } // Commit path. |
