Skip to content

Commit 64b0d0c

Browse files
mysticateanzakas
authored andcommitted
Fix: failed to parse /*eslint comments by colon (fixes #6224) (#6258)
It came to use Optionator to parse the comments by the same way as parsing CLI option. But Optionator cannot parse commaless notation, so there is a fallback for that.
1 parent c8936eb commit 64b0d0c

File tree

4 files changed

+75
-17
lines changed

4 files changed

+75
-17
lines changed

lib/config/config-ops.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ var RULE_SEVERITY_STRINGS = ["off", "warn", "error"],
2323
RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce(function(map, value, index) {
2424
map[value] = index;
2525
return map;
26-
}, {});
26+
}, {}),
27+
VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"];
2728

2829
//------------------------------------------------------------------------------
2930
// Public Interface
@@ -248,6 +249,30 @@ module.exports = {
248249
}
249250

250251
return (typeof severity === "number" && severity === 2);
251-
}
252+
},
252253

254+
/**
255+
* Checks whether a given config has valid severity or not.
256+
* @param {number|string|Array} ruleConfig - The configuration for an individual rule.
257+
* @returns {boolean} `true` if the configuration has valid severity.
258+
*/
259+
isValidSeverity: function(ruleConfig) {
260+
var severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
261+
262+
if (typeof severity === "string") {
263+
severity = severity.toLowerCase();
264+
}
265+
return VALID_SEVERITIES.indexOf(severity) !== -1;
266+
},
267+
268+
/**
269+
* Checks whether every rule of a given config has valid severity or not.
270+
* @param {object} config - The configuration for rules.
271+
* @returns {boolean} `true` if the configuration has valid severity.
272+
*/
273+
isEverySeverityValid: function(config) {
274+
return Object.keys(config).every(function(ruleId) {
275+
return this.isValidSeverity(config[ruleId]);
276+
}, this);
277+
}
253278
};

lib/eslint.js

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,25 @@
99
// Requirements
1010
//------------------------------------------------------------------------------
1111

12-
var lodash = require("lodash"),
13-
Traverser = require("./util/traverser"),
12+
var assert = require("assert"),
13+
EventEmitter = require("events").EventEmitter,
1414
escope = require("escope"),
15-
Environments = require("./config/environments"),
15+
levn = require("levn"),
16+
lodash = require("lodash"),
1617
blankScriptAST = require("../conf/blank-script.json"),
17-
rules = require("./rules"),
18-
RuleContext = require("./rule-context"),
19-
timing = require("./timing"),
20-
SourceCode = require("./util/source-code"),
21-
NodeEventGenerator = require("./util/node-event-generator"),
22-
CommentEventGenerator = require("./util/comment-event-generator"),
23-
EventEmitter = require("events").EventEmitter,
18+
DEFAULT_PARSER = require("../conf/eslint.json").parser,
19+
replacements = require("../conf/replacements.json"),
20+
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
2421
ConfigOps = require("./config/config-ops"),
2522
validator = require("./config/config-validator"),
26-
replacements = require("../conf/replacements.json"),
27-
assert = require("assert"),
28-
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer");
29-
30-
var DEFAULT_PARSER = require("../conf/eslint.json").parser;
23+
Environments = require("./config/environments"),
24+
CommentEventGenerator = require("./util/comment-event-generator"),
25+
NodeEventGenerator = require("./util/node-event-generator"),
26+
SourceCode = require("./util/source-code"),
27+
Traverser = require("./util/traverser"),
28+
RuleContext = require("./rule-context"),
29+
rules = require("./rules"),
30+
timing = require("./timing");
3131

3232
//------------------------------------------------------------------------------
3333
// Helpers
@@ -80,6 +80,25 @@ function parseBooleanConfig(string, comment) {
8080
function parseJsonConfig(string, location, messages) {
8181
var items = {};
8282

83+
// Parses a JSON-like comment by the same way as parsing CLI option.
84+
try {
85+
items = levn.parse("Object", string) || {};
86+
87+
// Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
88+
// Also, commaless notations have invalid severity:
89+
// "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
90+
// Should ignore that case as well.
91+
if (ConfigOps.isEverySeverityValid(items)) {
92+
return items;
93+
}
94+
} catch (ex) {
95+
96+
// ignore to parse the string by a fallback.
97+
}
98+
99+
// Optionator cannot parse commaless notations.
100+
// But we are supporting that. So this is a fallback for that.
101+
items = {};
83102
string = string.replace(/([a-zA-Z0-9\-\/]+):/g, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/, "$1,");
84103
try {
85104
items = JSON.parse("{" + string + "}");

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"is-resolvable": "^1.0.0",
5656
"js-yaml": "^3.5.1",
5757
"json-stable-stringify": "^1.0.0",
58+
"levn": "^0.3.0",
5859
"lodash": "^4.0.0",
5960
"mkdirp": "^0.5.0",
6061
"optionator": "^0.8.1",

tests/lib/eslint.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,19 @@ describe("eslint", function() {
25152515
});
25162516
});
25172517

2518+
describe("when evaluating code with comments which have colon in its value", function() {
2519+
var code = "/* eslint max-len: [2, 100, 2, {ignoreUrls: true, ignorePattern: \"data:image\\/|\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-\"}] */\nalert('test');";
2520+
2521+
it("should not parse errors, should report a violation", function() {
2522+
var messages = eslint.verify(code, {}, filename);
2523+
2524+
assert.equal(messages.length, 1);
2525+
assert.equal(messages[0].ruleId, "max-len");
2526+
assert.equal(messages[0].message, "Line 1 exceeds the maximum line length of 100.");
2527+
assert.include(messages[0].nodeType, "Program");
2528+
});
2529+
});
2530+
25182531
describe("when evaluating a file with a shebang", function() {
25192532
var code = "#!bin/program\n\nvar foo;;";
25202533

0 commit comments

Comments
 (0)