Skip to content

Conversation

@huseyinacacak-janea
Copy link
Contributor

@huseyinacacak-janea huseyinacacak-janea commented Aug 6, 2024

This PR fixes resolving device paths like \\.\PHYSICALDRIVE.
The resolve function was adding a trailing backslash, considering that this device path was a UNC path. However, device paths are different than UNC paths.

This PR includes more changes than originally intended because fixing the bug caused inconsistencies between other functions and operating systems. Now, this PR fixes all these problems.

Fixes: #54025

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. path Issues and PRs related to the path subsystem. labels Aug 6, 2024
@anonrig anonrig added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 6, 2024
@avivkeller avivkeller added the windows Issues and PRs related to the Windows platform. label Aug 6, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 6, 2024
@nodejs-github-bot

This comment was marked as outdated.

@codecov
Copy link

codecov bot commented Aug 6, 2024

Codecov Report

Attention: Patch coverage is 90.32258% with 12 lines in your changes missing coverage. Please review.

Project coverage is 87.89%. Comparing base (b4fd1fd) to head (34839d8).
Report is 441 commits behind head on main.

Files with missing lines Patch % Lines
src/path.cc 38.46% 6 Missing and 2 partials ⚠️
lib/path.js 95.91% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #54224      +/-   ##
==========================================
+ Coverage   87.06%   87.89%   +0.83%     
==========================================
  Files         643      651       +8     
  Lines      181576   183425    +1849     
  Branches    34894    35744     +850     
==========================================
+ Hits       158088   161222    +3134     
+ Misses      16759    15476    -1283     
+ Partials     6729     6727       -2     
Files with missing lines Coverage Δ
lib/internal/modules/cjs/loader.js 96.19% <100.00%> (+3.26%) ⬆️
lib/internal/url.js 98.70% <ø> (+3.93%) ⬆️
lib/path.js 97.27% <95.91%> (+1.33%) ⬆️
src/path.cc 67.39% <38.46%> (-1.66%) ⬇️

... and 206 files with indirect coverage changes

@anonrig anonrig added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Aug 6, 2024
`\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`;
rootEnd = j;
} else {
// We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0)
Copy link
Member

@lpinca lpinca Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should also handle \\?\PHYSICALDRIVE0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. Fixed.

Copy link
Member

@lpinca lpinca Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other inconsistencies:

path.resolve('\\\\?\\c:/')    // \\?\c:
path.toNamespacedPath('c:/')  // \\?\c:\

path.normalize('\\\\.\\foo')  // \\.\foo\
path.resolve('\\\\.\\foo\\')  // \\.\foo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll try to fix these inconsistencies. I have a question.
Node currently runs as follows:

path.resolve("C:\\")            // C:\\
path.resolve("//server/share")  // \\\\server\\share\\

But, I think it should be:

path.resolve("C:\\")            // C:
path.resolve("//server/share")  // \\\\server\\share

If I change these ones, resolve could return all the paths without any trailing backslash.
If I don't change them, the inconsistency below will still exist:

path.resolve("//server/share/folder")  // \\\\server\\share\\folder
path.resolve("//server/share")         // \\\\server\\share\\

What do you think?

Copy link
Member

@lpinca lpinca Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should respect the original input. If there is a trailing slash, keep it, otherwise do not add it.

$ python
Python 3.12.4 (tags/v3.12.4:8e8a4ba, Jun  6 2024, 19:30:16) [MSC v.1940 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import PurePath
>>> PurePath('c:/')
PureWindowsPath('c:/')
>>> PurePath('c:')
PureWindowsPath('c:')
>>> PurePath('c:', '\\\\.\\foo')
PureWindowsPath('//./foo')
>>> PurePath('c:', '\\\\.\\foo\\')
PureWindowsPath('//./foo/')
>>>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK \\?\... is not supposed to be subject to normalization, see this post.

Copy link
Contributor Author

@huseyinacacak-janea huseyinacacak-janea Aug 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My latest commit fixes the inconsistencies in resolve, toNamespacedPath and normalize on Windows. I'm open to suggestions and waiting for your reviews.
If there are no objections, I'll fix the inconsistencies between Windows and Posix that occurred after the last commit.

@huseyinacacak-janea huseyinacacak-janea force-pushed the huseyin-12382-physicaldrive-open-is-broken branch from b40e78c to ab4ad3b Compare August 7, 2024 08:35
@huseyinacacak-janea huseyinacacak-janea force-pushed the huseyin-12382-physicaldrive-open-is-broken branch 2 times, most recently from 888faf2 to 69c609d Compare August 15, 2024 06:02
@huseyinacacak-janea huseyinacacak-janea force-pushed the huseyin-12382-physicaldrive-open-is-broken branch 2 times, most recently from 4e2dddd to 1601604 Compare August 15, 2024 08:38
@huseyinacacak-janea huseyinacacak-janea force-pushed the huseyin-12382-physicaldrive-open-is-broken branch from 1601604 to a5540cb Compare August 16, 2024 12:46
@lpinca lpinca added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 16, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 16, 2024
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@huseyinacacak-janea
Copy link
Contributor Author

Is there anything else I can do to help this PR move forward?
Note that since this PR includes a lot of breaking changes, I think it would be better to label this as semver-major.

@lpinca lpinca added the semver-major PRs that contain breaking changes and should be released in the next major version. label Aug 21, 2024
@lpinca
Copy link
Member

lpinca commented Aug 21, 2024

@nodejs/path @nodejs/tsc

@lpinca lpinca changed the title path,win: fix bug in resolve path: fix bugs and inconsistencies Aug 22, 2024
@ShenHongFei
Copy link
Contributor

@huseyinacacak-janea @anonrig @lpinca

This change modifies the return results of path.resolve and path.relative, which will cause many third-party libraries to suddenly stop working. Please carefully consider whether you really want to change this way.
I encountered an error with npm publish. The main reason for the impact is that npm's processing of paths depends on resolve and relative functions, which will automatically remove the trailing /

npm publish error log
0 verbose cli D:\1\nodejs\node.exe D:\1\nodejs\node_modules\npm\bin\npm-cli.js
1 info using [email protected]
2 info using [email protected]
3 silly config load:file:D:\1\nodejs\node_modules\npm\npmrc
4 silly config load:file:D:\1\xsh\.npmrc
5 silly config load:file:C:\Users\shf\.npmrc
6 silly config load:file:D:\1\nodejs\etc\npmrc
7 verbose title npm publish
8 verbose argv "publish" "--proxy" "http://127.0.0.1:10080" "--registry" "https://registry.npmjs.org/"
9 verbose logfile logs-max:10 dir:T:\t\npm-cache\_logs\2024-09-19T16_52_55_988Z-
10 verbose logfile T:\t\npm-cache\_logs\2024-09-19T16_52_55_988Z-debug-0.log
11 verbose publish [ '.' ]
12 silly logfile start cleaning logs, removing 1 files
13 silly logfile done cleaning log files
14 verbose stack Error: ENOENT: no such file or directory, open 'D:\1\README.md'
14 verbose stack     at async open (node:internal/fs/promises:639:25)
14 verbose stack     at async Object.readFile (node:internal/fs/promises:1239:14)
14 verbose stack     at async normalize (D:\1\nodejs\node_modules\npm\node_modules\@npmcli\package-json\lib\normalize.js:348:26)
14 verbose stack     at async PackageJson.prepare (D:\1\nodejs\node_modules\npm\node_modules\@npmcli\package-json\lib\index.js:266:5)
14 verbose stack     at async #getManifest (D:\1\nodejs\node_modules\npm\lib\commands\publish.js:209:27)
14 verbose stack     at async #publish (D:\1\nodejs\node_modules\npm\lib\commands\publish.js:93:20)
14 verbose stack     at async Publish.exec (D:\1\nodejs\node_modules\npm\lib\commands\publish.js:46:5)
14 verbose stack     at async Npm.exec (D:\1\nodejs\node_modules\npm\lib\npm.js:207:9)
14 verbose stack     at async module.exports (D:\1\nodejs\node_modules\npm\lib\cli\entry.js:74:5)
15 error code ENOENT
16 error syscall open
17 error path D:\1\README.md
18 error errno -4058
19 error enoent ENOENT: no such file or directory, open 'D:\1\README.md'
20 error enoent This is related to npm not being able to find a file.
20 error enoent
21 verbose cwd D:\1\xsh
22 verbose os Windows_NT 10.0.22631
23 verbose node v23.0.0
24 verbose npm  v10.8.3
25 verbose exit -4058
26 verbose code -4058
27 error A complete log of this run can be found in: T:\t\npm-cache\_logs\2024-09-19T16_52_55_988Z-debug-0.log

The relevant code for the error in npm is as follows:

https://github.com/npm/npm-package-arg/blob/a8a9bddc726802fb5ed30f6b113d57f0655bbd51/lib/npa.js#L296

The reason for the error is that the following function returns inconsistent results:

// main branch
path.resolve('D:\\1\\xsh\\') === 'D:\\1\\xsh\\'
path.relative('D:\\1\\xsh', 'D:\\1\\xsh\\') === '..\\xsh'

// node.js v22.9.0
path.resolve('D:\\1\\xsh\\') === 'D:\\1\\xsh'
path.relative('D:\\1\\xsh', 'D:\\1\\xsh\\') === ''

@lpinca
Copy link
Member

lpinca commented Sep 19, 2024

Ok, if it too breaking of a change, I think we should revert efbba60 and reopen #54025.

path.relative('D:\\1\\xsh', 'D:\\1\\xsh\\') === '..\\xsh'

The above result is weird.

@lpinca
Copy link
Member

lpinca commented Sep 19, 2024

Maybe we can limit the scope and go back to b40e78c.

@avivkeller
Copy link
Member

This did not fix that issue, in fact, the fix is a revert of this #55414

@vzaidman
Copy link

This did not fix that issue, in fact, the fix is a revert of this #55414

oops, commented on the wrong PR. deleted the comment to not create confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-failed An error occurred while landing this pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-citgm PRs that need a CITGM CI run. path Issues and PRs related to the path subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. windows Issues and PRs related to the Windows platform.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

require('fs').openSync('\\\\.\\PhysicalDrive2', fs.constants.O_RDWR) is broken