Skip to content

Commit af0ee79

Browse files
bmeckaduh95
authored andcommitted
module: ensure relative requires work from deleted directories
1 parent 1422e51 commit af0ee79

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,14 @@ function resolveExports(nmPath, request) {
539539
}
540540

541541
const trailingSlashRegex = /(?:^|\/)\.?\.$/;
542+
const nixRelativeCheck = /^\.\.?(?:[/]|$)/;
543+
const windowsRelativeCheck = /^\.\.?(?:[/\\]|$)/;
544+
/**
545+
* @param {string} request a relative or absolute file path
546+
* @param {Array<string>} paths file system directories to search as file paths
547+
* @param {boolean} isMain if the request is the main app entry point
548+
* @returns {string | false}
549+
*/
542550
Module._findPath = function(request, paths, isMain) {
543551
const absoluteRequest = path.isAbsolute(request);
544552
if (absoluteRequest) {
@@ -560,11 +568,20 @@ Module._findPath = function(request, paths, isMain) {
560568
trailingSlash = RegExpPrototypeExec(trailingSlashRegex, request) !== null;
561569
}
562570

571+
const isRelative = RegExpPrototypeExec(isWindows ? windowsRelativeCheck : nixRelativeCheck, request) !== null;
572+
let insidePath = true;
573+
if (isRelative) {
574+
const normalizedRequest = path.normalize(request);
575+
if (StringPrototypeStartsWith(normalizedRequest, '..')) {
576+
insidePath = false;
577+
}
578+
}
579+
563580
// For each path
564581
for (let i = 0; i < paths.length; i++) {
565-
// Don't search further if path doesn't exist
582+
// Don't search further if path doesn't exist and request is inside the path
566583
const curPath = paths[i];
567-
if (curPath && _stat(curPath) < 1) continue;
584+
if (insidePath && curPath && _stat(curPath) < 1) continue;
568585

569586
if (!absoluteRequest) {
570587
const exportsResolved = resolveExports(curPath, request);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const tmpdir = require('../common/tmpdir');
5+
const assert = require('assert');
6+
const fs = require('fs');
7+
const path = require('path');
8+
9+
tmpdir.refresh();
10+
11+
const fooPath = path.join(tmpdir.path, 'foo.cjs');
12+
fs.writeFileSync(fooPath, '');
13+
14+
const dirPath = path.join(tmpdir.path, 'delete_me');
15+
fs.mkdirSync(dirPath, {
16+
recursive: true
17+
});
18+
19+
const barPath = path.join(dirPath, 'bar.cjs');
20+
fs.writeFileSync(barPath, `
21+
module.exports = () => require('../foo.cjs').call()
22+
`);
23+
24+
const foo = require(fooPath);
25+
const unique = Symbol('unique');
26+
foo.call = common.mustCall(() => unique);
27+
const bar = require(barPath);
28+
29+
fs.rmSync(dirPath, { recursive: true });
30+
assert.strict.equal(bar(), unique);

0 commit comments

Comments
 (0)