diff --git a/lib/config.js b/lib/config.js index 7b960f8998a4..1f9242f41f00 100644 --- a/lib/config.js +++ b/lib/config.js @@ -118,13 +118,13 @@ class Config { }; this.cliConfig = {}; - Object.keys(cliConfigOptions).forEach(function(configKey) { + Object.keys(cliConfigOptions).forEach(configKey => { const value = cliConfigOptions[configKey]; if (value) { this.cliConfig[configKey] = value; } - }, this); + }); } /** @@ -290,7 +290,7 @@ class Config { return; } - const relativePath = (filePath || directory).substr(config.baseDirectory.length + 1); + const relativePath = path.relative(config.baseDirectory, filePath || directory); overrides.forEach((override, i) => { if (ConfigOps.pathMatchesGlobs(relativePath, override.files)) { diff --git a/lib/config/config-file.js b/lib/config/config-file.js index 0dcd6ebfb2a1..14cf0639f716 100644 --- a/lib/config/config-file.js +++ b/lib/config/config-file.js @@ -567,13 +567,12 @@ function loadObject(configObject) { */ function loadCached(filePath) { const cachedConfig = configCache.getConfig(filePath); - let config = {}; if (cachedConfig) { return cachedConfig; } - config = load(filePath); + const config = load(filePath); if (config) { config.filePath = filePath; diff --git a/lib/config/config-ops.js b/lib/config/config-ops.js index f8f04e2dd184..5c4b72eff0f1 100644 --- a/lib/config/config-ops.js +++ b/lib/config/config-ops.js @@ -11,7 +11,8 @@ const Environments = require("./environments"), configCache = require("./config-cache"), - minimatch = require("minimatch"); + minimatch = require("minimatch"), + path = require("path"); const debug = require("debug")("eslint:config-ops"); @@ -289,12 +290,13 @@ module.exports = { nearestCacheIndex = vector.length - 1; // Check the merged vector config cache to try to find a merged config for the current config or a parent - for (; nearestCacheIndex >= 0; nearestCacheIndex--) { + while (nearestCacheIndex >= 0) { config = configCache.getMergedVectorConfig(subvector); if (config) { break; } subvector.pop(); + nearestCacheIndex--; } if (config) { @@ -349,7 +351,12 @@ module.exports = { * @returns {boolean} True if all the supplied patterns match the file path, false otherwise */ pathMatchesGlobs(filePath, patterns) { - patterns = [].concat(patterns); - return patterns.every(pattern => minimatch(filePath, pattern, { matchBase: true })); + const validPatterns = [].concat(patterns).filter( + pattern => !path.isAbsolute(pattern) && !pattern.includes("..") + ); + + return validPatterns.length > 0 && validPatterns.every( + pattern => minimatch(filePath, pattern, { matchBase: true }) + ); } }; diff --git a/tests/lib/config.js b/tests/lib/config.js index 0dcd22e8631f..69c3d1017d5e 100644 --- a/tests/lib/config.js +++ b/tests/lib/config.js @@ -1157,6 +1157,32 @@ describe("Config", () => { assertConfigsEqual(actual, expected); }); + it("should not merge override config when the pattern traverses up the directory tree", () => { + const targetPath = getFakeFixturePath("overrides", "bar.js"); + const parentPath = "overrides/../**/*.js"; + + const config = new Config({ + cwd: process.cwd(), + baseConfig: { + overrides: [{ + files: parentPath, + rules: { + quotes: [2, "single"] + } + }], + useEslintrc: false + } + }); + const expected = { + rules: { + quotes: [2, "double"] + } + }; + const actual = config.getConfig(targetPath); + + assertConfigsEqual(actual, expected); + }); + it("should merge all local configs (override and non-override) before non-local configs", () => { const config = new Config({ cwd: process.cwd() }); const targetPath = getFakeFixturePath("overrides", "two", "child-two.js");