Skip to content

Commit

Permalink
module: ensure relative requires work from deleted directories
Browse files Browse the repository at this point in the history
  • Loading branch information
bmeck authored and aduh95 committed Oct 28, 2022
1 parent 1422e51 commit af0ee79
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lib/internal/modules/cjs/loader.js
Expand Up @@ -539,6 +539,14 @@ function resolveExports(nmPath, request) {
}

const trailingSlashRegex = /(?:^|\/)\.?\.$/;
const nixRelativeCheck = /^\.\.?(?:[/]|$)/;
const windowsRelativeCheck = /^\.\.?(?:[/\\]|$)/;
/**
* @param {string} request a relative or absolute file path
* @param {Array<string>} paths file system directories to search as file paths
* @param {boolean} isMain if the request is the main app entry point
* @returns {string | false}
*/
Module._findPath = function(request, paths, isMain) {
const absoluteRequest = path.isAbsolute(request);
if (absoluteRequest) {
Expand All @@ -560,11 +568,20 @@ Module._findPath = function(request, paths, isMain) {
trailingSlash = RegExpPrototypeExec(trailingSlashRegex, request) !== null;
}

const isRelative = RegExpPrototypeExec(isWindows ? windowsRelativeCheck : nixRelativeCheck, request) !== null;
let insidePath = true;
if (isRelative) {
const normalizedRequest = path.normalize(request);
if (StringPrototypeStartsWith(normalizedRequest, '..')) {
insidePath = false;
}
}

// For each path
for (let i = 0; i < paths.length; i++) {
// Don't search further if path doesn't exist
// Don't search further if path doesn't exist and request is inside the path
const curPath = paths[i];
if (curPath && _stat(curPath) < 1) continue;
if (insidePath && curPath && _stat(curPath) < 1) continue;

if (!absoluteRequest) {
const exportsResolved = resolveExports(curPath, request);
Expand Down
30 changes: 30 additions & 0 deletions test/parallel/test-require-enoent-dir.js
@@ -0,0 +1,30 @@
'use strict';

const common = require('../common');
const tmpdir = require('../common/tmpdir');
const assert = require('assert');
const fs = require('fs');
const path = require('path');

tmpdir.refresh();

const fooPath = path.join(tmpdir.path, 'foo.cjs');
fs.writeFileSync(fooPath, '');

const dirPath = path.join(tmpdir.path, 'delete_me');
fs.mkdirSync(dirPath, {
recursive: true
});

const barPath = path.join(dirPath, 'bar.cjs');
fs.writeFileSync(barPath, `
module.exports = () => require('../foo.cjs').call()
`);

const foo = require(fooPath);
const unique = Symbol('unique');
foo.call = common.mustCall(() => unique);
const bar = require(barPath);

fs.rmSync(dirPath, { recursive: true });
assert.strict.equal(bar(), unique);

0 comments on commit af0ee79

Please sign in to comment.