Skip to content

Regression: require.resolve(".", { paths }) behaves differently from require.resolve("./", { paths }) #47000

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
tolmasky opened this issue Mar 7, 2023 · 1 comment · Fixed by #56735

Comments

@tolmasky
Copy link
Contributor

tolmasky commented Mar 7, 2023

Version

18.14.2

Platform

22.3.0 Darwin Kernel Version 22.3.0

Subsystem

loader

What steps will reproduce the bug?

home:/$ docker run --rm -it node:18.14.2-slim bash
node:/# echo "['./', '.'].map(request => console.log(require.resolve(request, { paths: ['..'] })))" > index.js
node:/# mkdir test && cd test
node:/# node ../index.js

This produces:

> /index.js
> node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module '.'
Require stack:
- /index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at /index.js:1:48
    at Array.map (<anonymous>)
    at Object.<anonymous> (/index.js:1:13)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/index.js' ]
}
node:/#

The same is true of .. and ../. I leave that as an exercise to the reader. If you rerun the above in node 10, you get the same log for both, as expected:

home:/$ docker run --rm -it node:10.24.1-slim bash
node:/# echo "['./', '.'].map(request => console.log(require.resolve(request, { paths: ['..'] })))" > index.js
node:/# mkdir test && cd test
node:/# node ../index.js
/index.js
/index.js
node:/#

If you want to get more clever, you can put a index.js inside of the test directory, and then it'll just give you different results without crashing:

home:/$ docker run --rm -it node:18.14.2-slim bash
node:/# echo "['./', '.'].map(request => console.log(require.resolve(request, { paths: ['..'] })))" > index.js
node:/# mkdir test && cd test
node:/# echo "['./', '.'].map(request => console.log(require.resolve(request, { paths: ['..'] })))" > index.js
node:/# node ../index.js
/index.js
/test/index.js
node:/#

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior?

The same way it worked in node 10:

home:/$ docker run --rm -it node:10.24.1-slim bash
node:/# echo "['./', '.'].map(request => console.log(require.resolve(request, { paths: ['..'] })))" > index.js
node:/# mkdir test && cd test
node:/# node ../index.js
/index.js
/index.js
node:/#

What do you see instead?

Different file paths, crash, etc.

Additional information

This seems to be a result of this pull request: #27598

The code in Module._resolveFilename only checks for "./" and "../" to determine if the path is a relative path:

const isRelative = StringPrototypeStartsWith(request, './') ||
StringPrototypeStartsWith(request, '../') ||
((isWindows && StringPrototypeStartsWith(request, '.\\')) ||
StringPrototypeStartsWith(request, '..\\'));

Adding === "." and === ".." should fix the problem. Or, given that earlier in the file in Module._findPath the same thing is calculated slightly differently:

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)))

Perhaps this should be factored out into a isRelativePath function since it seems to be tricky enough to get right to not rely on separate inlined implementations in various different places.

@bjrmatos
Copy link

i just got hit by this today, and when debugging i found the solution the same as the linked PR #47019

is anything missing to fix this? or what needs to be done to move forward with the PR?

dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 23, 2025
dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 23, 2025
dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 23, 2025
dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 24, 2025
…tive

Fixes: nodejs#47000

add early return for perf gain

fix linting
dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 24, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: nodejs#47000
dario-piotrowicz added a commit to dario-piotrowicz/node that referenced this issue Jan 24, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: nodejs#47000
aduh95 pushed a commit that referenced this issue Jan 27, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
aduh95 pushed a commit that referenced this issue Jan 30, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
hvanness pushed a commit to hvanness/node that referenced this issue Jan 30, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: nodejs#47000
PR-URL: nodejs#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>
aduh95 pushed a commit that referenced this issue Jan 31, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
aduh95 pushed a commit that referenced this issue Feb 4, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
aduh95 pushed a commit that referenced this issue Feb 6, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
marco-ippolito pushed a commit that referenced this issue Mar 6, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
marco-ippolito pushed a commit that referenced this issue Mar 6, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
marco-ippolito pushed a commit that referenced this issue Mar 6, 2025
this change fixes `require.resolve` used with the `paths` option
not considering `.` and `..` as relative

Fixes: #47000
PR-URL: #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>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
2 participants