Skip to content

Commit ad5f274

Browse files
cpmsmithboopathi
authored andcommitted
Clone SVGO opts object before mutating it (#250)
1 parent b30818c commit ad5f274

File tree

5 files changed

+26
-29
lines changed

5 files changed

+26
-29
lines changed

packages/react-svg-core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@babel/plugin-syntax-jsx": "^7.2.0",
2626
"@babel/preset-react": "^7.0.0",
2727
"babel-plugin-react-svg": "^2.1.0",
28+
"lodash.clonedeep": "^4.5.0",
2829
"lodash.isplainobject": "^4.0.6",
2930
"svgo": "^1.2.2"
3031
},

packages/react-svg-core/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { validateAndFix } from "./svgo";
88

99
// SVGO Optimize
1010
export function optimize(opts: any = {}): string => Promise<string> {
11-
validateAndFix(opts);
11+
opts = validateAndFix(opts);
1212
const svgo = new Svgo(opts);
1313

1414
return (content: string) => svgo.optimize(content).then(data => data.data);

packages/react-svg-core/src/svgo.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// for the babylon JSX parser to work
66

77
import isPlainObject from "lodash.isplainobject";
8+
import cloneDeep from "lodash.clonedeep";
89

910
const essentialPlugins = [
1011
"removeDoctype",
@@ -16,13 +17,15 @@ export function validateAndFix(opts: any = {}) {
1617
if (!isPlainObject(opts))
1718
throw new Error("Expected options.svgo to be Object.");
1819

19-
if (opts.plugins === void 0) opts.plugins = [];
20+
let cleanOpts = cloneDeep(opts);
2021

21-
if (!Array.isArray(opts.plugins))
22+
if (cleanOpts.plugins === void 0) cleanOpts.plugins = [];
23+
24+
if (!Array.isArray(cleanOpts.plugins))
2225
throw new Error("Expected options.svgo.plugins to be an array");
2326

24-
if (opts.plugins.length === 0) {
25-
opts.plugins = [...essentialPlugins].map(p => ({ [p]: true }));
27+
if (cleanOpts.plugins.length === 0) {
28+
cleanOpts.plugins = [...essentialPlugins].map(p => ({ [p]: true }));
2629
}
2730

2831
const state = new Map();
@@ -32,7 +35,7 @@ export function validateAndFix(opts: any = {}) {
3235
}
3336

3437
// parse through input plugins and mark enabled ones
35-
for (const plugin of opts.plugins) {
38+
for (const plugin of cleanOpts.plugins) {
3639
if (isPlainObject(plugin)) {
3740
for (const pluginName of Object.keys(plugin)) {
3841
if (essentialPlugins.indexOf(pluginName) > -1) {
@@ -55,14 +58,16 @@ export function validateAndFix(opts: any = {}) {
5558
// add missing plugins
5659
for (const p of essentialPlugins) {
5760
if (!state.get(p)) {
58-
opts.plugins.push(p);
61+
cleanOpts.plugins.push(p);
5962
}
6063
}
6164

6265
// convert strings to objects to match the form svgo accepts
63-
for (let i = 0; i < opts.plugins.length; i++) {
64-
if (typeof opts.plugins[i] === "string") {
65-
opts.plugins[i] = { [opts.plugins[i]]: true };
66+
for (let i = 0; i < cleanOpts.plugins.length; i++) {
67+
if (typeof cleanOpts.plugins[i] === "string") {
68+
cleanOpts.plugins[i] = { [cleanOpts.plugins[i]]: true };
6669
}
6770
}
71+
72+
return cleanOpts;
6873
}

packages/react-svg-core/test/svgo.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import test from "tape";
33

44
test("fills essential plugins when empty", function(t) {
55
let opts = {};
6-
validateAndFix(opts);
6+
opts = validateAndFix(opts);
77
t.equal(opts.plugins.length, 3);
88
t.end();
99
});
@@ -13,7 +13,7 @@ test("enable disabled essential plugins", function(t) {
1313
full: true,
1414
plugins: ["removeDoctype", { removeComments: false }]
1515
};
16-
validateAndFix(opts);
16+
opts = validateAndFix(opts);
1717
t.equal(opts.plugins.length, 3);
1818
t.equal(opts.plugins[1].removeComments, true);
1919
t.end();

yarn.lock

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,15 +2426,6 @@ cmd-shim@^2.0.2:
24262426
graceful-fs "^4.1.2"
24272427
mkdirp "~0.5.0"
24282428

2429-
coa@^2.0.2:
2430-
version "2.0.2"
2431-
resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3"
2432-
integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==
2433-
dependencies:
2434-
"@types/q" "^1.5.1"
2435-
chalk "^2.4.1"
2436-
q "^1.1.2"
2437-
24382429
coa@~1.0.1:
24392430
version "1.0.4"
24402431
resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd"
@@ -2758,6 +2749,14 @@ csso@~2.3.1:
27582749
clap "^1.0.9"
27592750
source-map "^0.5.3"
27602751

2752+
csso@~2.3.1:
2753+
version "2.3.2"
2754+
resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85"
2755+
integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=
2756+
dependencies:
2757+
clap "^1.0.9"
2758+
source-map "^0.5.3"
2759+
27612760
currently-unhandled@^0.4.1:
27622761
version "0.4.1"
27632762
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -4857,14 +4856,6 @@ js-yaml@^3.12.0, js-yaml@^3.9.0:
48574856
argparse "^1.0.7"
48584857
esprima "^4.0.0"
48594858

4860-
js-yaml@^3.13.1:
4861-
version "3.13.1"
4862-
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
4863-
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
4864-
dependencies:
4865-
argparse "^1.0.7"
4866-
esprima "^4.0.0"
4867-
48684859
js-yaml@~3.7.0:
48694860
version "3.7.0"
48704861
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"

0 commit comments

Comments
 (0)