From 054371b38a0816df2962d33826631508c35b818f Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sat, 26 Jun 2021 17:11:32 +0800 Subject: [PATCH 1/2] fix: update svgo to non-vulnerable version (older version relied on bad `css-select` -> `css-what`) The vulnerability is described at https://snyk.io/vuln/SNYK-JS-CSSWHAT-1298035 Also: 1. updates devDeps. 2. fixes problem with numeric entities for `<` and `&` not being permissible when they should be (needed to keep a test passing as well as being a proper fix) --- index.js | 17 ++++++++++------- package.json | 14 +++++++------- v2.js | 25 ++++++++++++++----------- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 30984d1..876db40 100644 --- a/index.js +++ b/index.js @@ -5,8 +5,7 @@ Copyrights licensed under the New BSD License. See the accompanying LICENSE file var fs = require('fs'), path = require('path'), - SVGO = require('svgo'), - svgo = new SVGO(), + {optimize} = require('svgo'), dot = require('dot'), template = dot.template(fs.readFileSync(path.join(__dirname, 'templates', 'basic.svg'), 'utf-8')), v2 = require('./v2'), @@ -21,7 +20,7 @@ var fs = require('fs'), * @param {String} color Color text to pick * @param {Function} callback Function to call when done (error, SVG) */ -module.exports = function badge (field1, field2, color, callback) { +module.exports = async function badge (field1, field2, color, callback) { var data = { text: [ utils.escapeXml(field1), @@ -37,10 +36,14 @@ module.exports = function badge (field1, field2, color, callback) { }; // Run the SVG through SVGO. - return svgo.optimize(template(data)).then(function (object) { - if (callback) callback(null, object.data); - return object.data; - }); + const object = optimize( + template(data) + // Due to https://github.com/svg/svgo/issues/1498 + .replace(/&#(x3c|60);/gi, '<') + .replace(/&#(x26|38);/gi, '&') + ); + if (callback) callback(null, object.data); + return object.data; }; /** diff --git a/package.json b/package.json index 08121ad..30165f8 100644 --- a/package.json +++ b/package.json @@ -43,16 +43,16 @@ } }, "devDependencies": { - "chai": "^4.2.0", - "coveralls": "^3.0.11", - "eslint": "^6.8.0", - "mocha": "^7.1.1", - "nyc": "^15.0.0", - "sinon": "^9.0.1" + "chai": "^4.3.4", + "coveralls": "^3.1.1", + "eslint": "^8.5.0", + "mocha": "^9.1.3", + "nyc": "^15.1.0", + "sinon": "^12.0.1" }, "dependencies": { "css-color-names": "~1.0.1", "dot": "^1.1.3", - "svgo": "^1.3.2" + "svgo": "^2.8.0" } } diff --git a/v2.js b/v2.js index 8cc68ce..4d2bc74 100644 --- a/v2.js +++ b/v2.js @@ -8,12 +8,7 @@ var colors = require('css-color-names'), fs = require('fs'), path = require('path'), utils = require('./utils'), - SVGO = require('svgo'), - svgo = new SVGO({ - plugins: [{ - sortDefsChildren: false - }] - }), + {optimize, extendDefaultPlugins} = require('svgo'), TEMPLATE = dot.template(fs.readFileSync(path.join(__dirname, 'templates', 'v2.svg'), 'utf-8')), COLOR_REGEX = /^[0-9a-f]{6}$/i, STROKE_REGEX = /^s\{(.+?)\}$/i, @@ -100,12 +95,20 @@ function sectionsToData(sections) { } -module.exports = function badge_v2(sections, callback) { - var raw = TEMPLATE(sectionsToData(sections)); - return svgo.optimize(raw).then(function(optimized) { - if (callback) callback(undefined, optimized.data); - return optimized.data; +module.exports = async function badge_v2(sections, callback) { + var raw = TEMPLATE(sectionsToData(sections)) + // Due to https://github.com/svg/svgo/issues/1498 + .replace(/&#(x3c|60);/gi, '<') + .replace(/&#(x26|38);/gi, '&'); + + const optimized = optimize(raw, { + plugins: extendDefaultPlugins([{ + name: 'sortDefsChildren', + active: false + }]) }); + if (callback) callback(undefined, optimized.data); + return optimized.data; }; From 35271d9694776256fc6233883a87dacfb4a62630 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Wed, 22 Dec 2021 20:41:56 +0800 Subject: [PATCH 2/2] refactor: es6 features --- index.js | 4 ++-- v2.js | 40 ++++++++++++++++++---------------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/index.js b/index.js index 876db40..6de856e 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ Copyright (c) 2016, Yahoo Inc. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ -var fs = require('fs'), +const fs = require('fs'), path = require('path'), {optimize} = require('svgo'), dot = require('dot'), @@ -21,7 +21,7 @@ var fs = require('fs'), * @param {Function} callback Function to call when done (error, SVG) */ module.exports = async function badge (field1, field2, color, callback) { - var data = { + const data = { text: [ utils.escapeXml(field1), utils.escapeXml(field2) diff --git a/v2.js b/v2.js index 4d2bc74..ecbb7d8 100644 --- a/v2.js +++ b/v2.js @@ -3,7 +3,7 @@ Copyright (c) 2016, Yahoo Inc. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ -var colors = require('css-color-names'), +const colors = require('css-color-names'), dot = require('dot'), fs = require('fs'), path = require('path'), @@ -38,29 +38,26 @@ function getColorCode(input) { } function sectionsToData(sections) { - var badgeData = { + const badgeData = { width: 0, height: 0, sections: [], }; sections.forEach(function(section, s) { - var sectionData = { - x: 0, - width: 0, - lines: [], - }, - sectionHeight, - text, - lines; + const sectionData = { + x: 0, + width: 0, + lines: [], + }; if (! Array.isArray(section)) { section = [ section ]; } - text = section.shift(); + const text = section.shift(); sectionData.x = badgeData.width; sectionData.color = (s === 0 ? DEFAULT_COLOR_FIRST : DEFAULT_COLOR_REST); section.forEach(function(attribute) { // stroke attribute `s{color}` as CSS color or color code in hex - var strokeAttribute = STROKE_REGEX.exec(attribute); + const strokeAttribute = STROKE_REGEX.exec(attribute); if (strokeAttribute) { sectionData.stroke = getColorCode(strokeAttribute[1]) || null; } @@ -72,22 +69,21 @@ function sectionsToData(sections) { // FUTURE -- text alignment `a{align}` lmr (only matters when multiline) // FUTURE -- font `f{font}` mainly for monospace (`fm`) }); - lines = text.split('\n'); + const lines = text.split('\n'); lines.forEach(function(line, l) { - var lineData = { - x: 0, - y: 0, - text: line, - }, - lineWidth; - lineWidth = (2 * PAD_X) + utils.textWidth(lineData.text, DEFAULT_LETTER_WIDTH); + const lineData = { + x: 0, + y: 0, + text: line, + }; + const lineWidth = (2 * PAD_X) + utils.textWidth(lineData.text, DEFAULT_LETTER_WIDTH); lineData.x = badgeData.width + PAD_X; lineData.y = (LINE_HEIGHT * l) + PAD_Y + LINE_HEIGHT - DECENDER_HEIGHT; sectionData.lines.push(lineData); sectionData.width = Math.max(sectionData.width, lineWidth); }); badgeData.sections.push(sectionData); - sectionHeight = (2 * PAD_Y) + (lines.length * LINE_HEIGHT); + const sectionHeight = (2 * PAD_Y) + (lines.length * LINE_HEIGHT); badgeData.height = Math.max(badgeData.height, sectionHeight); badgeData.width += sectionData.width; }); @@ -96,7 +92,7 @@ function sectionsToData(sections) { module.exports = async function badge_v2(sections, callback) { - var raw = TEMPLATE(sectionsToData(sections)) + const raw = TEMPLATE(sectionsToData(sections)) // Due to https://github.com/svg/svgo/issues/1498 .replace(/&#(x3c|60);/gi, '<') .replace(/&#(x26|38);/gi, '&');