mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
module: fix bad require.resolve
with option paths for .
and ..
this change fixes `require.resolve` used with the `paths` option not considering `.` and `..` as relative Fixes: https://github.com/nodejs/node/issues/47000 PR-URL: https://github.com/nodejs/node/pull/56735 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jordan Harband <ljharb@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
59b3a8b21b
commit
7119303a81
3 changed files with 61 additions and 17 deletions
|
@ -722,18 +722,8 @@ Module._findPath = function(request, paths, isMain, conditions = getCjsCondition
|
|||
)
|
||||
));
|
||||
|
||||
const isRelative = StringPrototypeCharCodeAt(request, 0) === CHAR_DOT &&
|
||||
(
|
||||
request.length === 1 ||
|
||||
StringPrototypeCharCodeAt(request, 1) === CHAR_FORWARD_SLASH ||
|
||||
(isWindows && StringPrototypeCharCodeAt(request, 1) === CHAR_BACKWARD_SLASH) ||
|
||||
(StringPrototypeCharCodeAt(request, 1) === CHAR_DOT && ((
|
||||
request.length === 2 ||
|
||||
StringPrototypeCharCodeAt(request, 2) === CHAR_FORWARD_SLASH) ||
|
||||
(isWindows && StringPrototypeCharCodeAt(request, 2) === CHAR_BACKWARD_SLASH)))
|
||||
);
|
||||
let insidePath = true;
|
||||
if (isRelative) {
|
||||
if (isRelative(request)) {
|
||||
const normalizedRequest = path.normalize(request);
|
||||
if (StringPrototypeStartsWith(normalizedRequest, '..')) {
|
||||
insidePath = false;
|
||||
|
@ -1328,12 +1318,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
|
|||
|
||||
if (typeof options === 'object' && options !== null) {
|
||||
if (ArrayIsArray(options.paths)) {
|
||||
const isRelative = StringPrototypeStartsWith(request, './') ||
|
||||
StringPrototypeStartsWith(request, '../') ||
|
||||
((isWindows && StringPrototypeStartsWith(request, '.\\')) ||
|
||||
StringPrototypeStartsWith(request, '..\\'));
|
||||
|
||||
if (isRelative) {
|
||||
if (isRelative(request)) {
|
||||
paths = options.paths;
|
||||
} else {
|
||||
const fakeParent = new Module('', null);
|
||||
|
@ -1978,6 +1963,21 @@ function createRequire(filename) {
|
|||
return createRequireFromPath(filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a path is relative
|
||||
* @param {string} path the target path
|
||||
* @returns {boolean} true if the path is relative, false otherwise
|
||||
*/
|
||||
function isRelative(path) {
|
||||
if (StringPrototypeCharCodeAt(path, 0) !== CHAR_DOT) { return false; }
|
||||
|
||||
return path.length === 1 || path === '..' ||
|
||||
StringPrototypeStartsWith(path, './') ||
|
||||
StringPrototypeStartsWith(path, '../') ||
|
||||
((isWindows && StringPrototypeStartsWith(path, '.\\')) ||
|
||||
StringPrototypeStartsWith(path, '..\\'));
|
||||
}
|
||||
|
||||
Module.createRequire = createRequire;
|
||||
|
||||
/**
|
||||
|
|
1
test/fixtures/module-require/relative/subdir/relative-subdir.js
vendored
Normal file
1
test/fixtures/module-require/relative/subdir/relative-subdir.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
exports.value = 'relative subdir';
|
43
test/parallel/test-require-resolve-opts-paths-relative.js
Normal file
43
test/parallel/test-require-resolve-opts-paths-relative.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
if (!common.isMainThread)
|
||||
common.skip('process.chdir is not available in Workers');
|
||||
|
||||
const subdir = fixtures.path('module-require', 'relative', 'subdir');
|
||||
|
||||
process.chdir(subdir);
|
||||
|
||||
// Parent directory paths (`..`) work as intended
|
||||
{
|
||||
assert(require.resolve('.', { paths: ['../'] }).endsWith('index.js'));
|
||||
assert(require.resolve('./index.js', { paths: ['../'] }).endsWith('index.js'));
|
||||
|
||||
// paths: [".."] should resolve like paths: ["../"]
|
||||
assert(require.resolve('.', { paths: ['..'] }).endsWith('index.js'));
|
||||
assert(require.resolve('./index.js', { paths: ['..'] }).endsWith('index.js'));
|
||||
}
|
||||
|
||||
process.chdir('..');
|
||||
|
||||
// Current directory paths (`.`) work as intended
|
||||
{
|
||||
assert(require.resolve('.', { paths: ['.'] }).endsWith('index.js'));
|
||||
assert(require.resolve('./index.js', { paths: ['./'] }).endsWith('index.js'));
|
||||
|
||||
// paths: ["."] should resolve like paths: ["../"]
|
||||
assert(require.resolve('.', { paths: ['.'] }).endsWith('index.js'));
|
||||
assert(require.resolve('./index.js', { paths: ['.'] }).endsWith('index.js'));
|
||||
}
|
||||
|
||||
// Sub directory paths work as intended
|
||||
{
|
||||
// assert.deepStrictEqual(fs.readdirSync('./subdir'), [5]);
|
||||
assert(require.resolve('./relative-subdir.js', { paths: ['./subdir'] }).endsWith('relative-subdir.js'));
|
||||
|
||||
// paths: ["subdir"] should resolve like paths: ["./subdir"]
|
||||
assert(require.resolve('./relative-subdir.js', { paths: ['subdir'] }).endsWith('relative-subdir.js'));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue