diff --git a/Gruntfile.js b/Gruntfile.js index d8c264ba..a59914c1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -41,6 +41,8 @@ module.exports = function(grunt) { build_dir: "build", //Parser lib copy for versions that can't use requirejs parserlib: "node_modules/parserlib/lib/node-parserlib.js", + //clone copy for versions that can't use requirejs + clone: "node_modules/clone/clone.js", //Core CSSLint files used by most versions csslint_files: [ "src/core/CSSLint.js", @@ -51,6 +53,7 @@ module.exports = function(grunt) { //Core fileset used by most versions core_files: [ "<%= parserlib %>", + "<%= clone %>", "<%= csslint_files %>" ], // Task configuration. @@ -86,6 +89,7 @@ module.exports = function(grunt) { node: { options: { banner: "<%= banner.full %>\n" + + "var clone = require('clone');\n" + "var parserlib = require('parserlib');\n", footer: "\nexports.CSSLint = CSSLint;" }, diff --git a/package.json b/package.json index 013a6fe8..eee7f7c6 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "test": "grunt test" }, "dependencies": { + "clone": "~0.1.11", "parserlib": "~0.2.4" }, "devDependencies": { diff --git a/src/core/CSSLint.js b/src/core/CSSLint.js index 61e41706..9c4f84ba 100644 --- a/src/core/CSSLint.js +++ b/src/core/CSSLint.js @@ -5,7 +5,7 @@ * @extends parserlib.util.EventTarget */ -/* global parserlib, Reporter */ +/* global parserlib, clone, Reporter */ /* exported CSSLint */ var CSSLint = (function(){ @@ -189,6 +189,8 @@ var CSSLint = (function(){ } if (embeddedRuleset.test(text)){ + //defensively copy so that caller's version does not get modified + ruleset = clone(ruleset); ruleset = applyEmbeddedRuleset(text, ruleset); } diff --git a/tests/core/CSSLint.js b/tests/core/CSSLint.js index 09627707..967feb5b 100644 --- a/tests/core/CSSLint.js +++ b/tests/core/CSSLint.js @@ -25,6 +25,18 @@ Assert.areEqual(2, result.ruleset["adjoining-classes"]); Assert.areEqual(1, result.ruleset["text-indent"]); Assert.areEqual(0, result.ruleset["box-sizing"]); + }, + + "Embedded rulesets should not have the side-effect of modifying the ruleset object passed in by the caller of verify()": function(){ + var ruleset = { + "text-indent": 1, + "box-sizing": 1 + }; + CSSLint.verify("/*csslint bogus, adjoining-classes:true, box-sizing:false */\n.foo.bar{}", ruleset); + + Assert.areEqual(undefined, ruleset["adjoining-classes"]); + Assert.areEqual(1, ruleset["text-indent"]); + Assert.areEqual(1, ruleset["box-sizing"]); } }));