From 75be89b17bb0f5515db1eafbda04c3a35f70aadd Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Mon, 30 Nov 2020 12:42:40 +0100 Subject: [PATCH] fix: improve resolve search logic (#697) * fix: improve resolve search logic * Only progress towards the root if file is not relative. --- packages/cspell-lib/src/util/resolveFile.ts | 28 ++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/cspell-lib/src/util/resolveFile.ts b/packages/cspell-lib/src/util/resolveFile.ts index b6c95bdcf586..93f9d473ae6a 100644 --- a/packages/cspell-lib/src/util/resolveFile.ts +++ b/packages/cspell-lib/src/util/resolveFile.ts @@ -21,6 +21,7 @@ const testNodeModules = /^node_modules\//; export function resolveFile(filename: string, relativeTo: string): ResolveFileResult { filename = filename.replace(/^~/, os.homedir()); const steps: { filename: string; fn: (f: string, r: string) => ResolveFileResult }[] = [ + { filename: filename, fn: tryNodeResolveDefaultPaths }, { filename: filename, fn: tryNodeResolve }, { filename: path.resolve(relativeTo, filename), fn: tryResolveExists }, { filename: path.resolve(filename), fn: tryResolveExists }, @@ -36,9 +37,34 @@ export function resolveFile(filename: string, relativeTo: string): ResolveFileRe return { filename: path.resolve(relativeTo, filename), relativeTo, found: false }; } +function tryNodeResolveDefaultPaths(filename: string): ResolveFileResult { + try { + const r = require.resolve(filename); + return { filename: r, relativeTo: undefined, found: true }; + } catch (_) { + return { filename, relativeTo: undefined, found: false }; + } +} + function tryNodeResolve(filename: string, relativeTo: string): ResolveFileResult { + const home = os.homedir(); + function calcPaths(p: string) { + const paths = [p]; + // Do not progress towards the root if it is a relative filename. + if ( + filename.startsWith('.') && + (filename.startsWith('./') || filename.startsWith('.' + path.sep) || filename.startsWith('..')) + ) { + return paths; + } + for (; p && path.dirname(p) !== p && p !== home; p = path.dirname(p)) { + paths.push(p); + } + return paths; + } + const paths = calcPaths(path.resolve(relativeTo)); try { - const r = require.resolve(filename, { paths: [path.resolve(relativeTo)] }); + const r = require.resolve(filename, { paths }); return { filename: r, relativeTo, found: true }; } catch (_) { return { filename, relativeTo, found: false };