-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
path.join('C:') = 'C:.' only in windows node LTS version #14405
Comments
In general, the path normalization behavior is platform-dependent. You might find Now, the issue itself is actually two issues as far as I can tell. The The join->parse->format issue is more complex: > path.win32.parse('C:')
{ root: 'C:', dir: 'C:', base: '', ext: '', name: '' }
> path.win32.parse('C:.')
{ root: 'C:', dir: '', base: 'C:.', ext: '', name: 'C:.' } // <-- ISSUE I would expect { root: 'C:', dir: 'C:', base: '.', ext: '', name: '.' } Similarly: > path.win32.parse('C:abcd')
{ root: 'C:', dir: '', base: 'C:abcd', ext: '', name: 'C:abcd' } seems to be faulty as well. |
These issues are also reproducible on master. |
Well, what can I say... Paths on Windows are a mess, and node really isn't dealing with that mess too well yet. Okay, the colon has three separate meanings under Windows, and it is not trivial to dinstinguish them:
C:\>echo A > F:\test\foo
C:\>type F:\test\foo
A
C:\>cd F:\test
C:\>echo foo > F:something
C:\>type F:\test\something
foo
F:\test>echo foo > test
F:\test>echo bar > test:alt
F:\test>streams test
streams v1.60 - Reveal NTFS alternate streams.
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
F:\test\test:
:alt:$DATA 6 This document describes some of these aspects. Consider this paragraph:
Note that
We always tried to keep the Note that the path API has some other platform-specific problems, mostly related to I will try to explain why some of your examples @XGHeaven and @TimothyGu are not as unambiguous as you might think: path.win32.join('C:') should either throw, return path.win32.join('C:\\') should return path.win32.join('C:', 'a') I am not sure whether path.win32.parse('C:') Again, this is not an absolute path: C:\>cd F:\test
C:\>dir F:
Verzeichnis von F:\test
22.07.2017 17:21 <DIR> .
22.07.2017 17:21 <DIR> ..
22.07.2017 17:17 16 foo
22.07.2017 17:20 6 something
22.07.2017 17:21 6 test path.win32.parse('C:abcd') I am not sure how we would represent this. tl;dr: cc @refack |
path.win32.join('C:') Whatever it return, I think path.win32.join('C:', 'a') I prefer to return path.win32.join('C:\\', 'a')
// or
path.win32.join('C:/', 'a') // don't care about using '/' or '\\' when you write cross-platform app And colon usage case 3 in windows, it never used in development or cmd for myself. |
Sometimes I wish GitHub would add 😭 as a reaction. |
Actually, beside being ugly d:\code\node-cur$ c:
C:\$ cd windows
C:\WINDOWS$ d:
d:\code\node-cur$ pushd c:.
C:\WINDOWS$ popd
d:\code\node-cur$ pushd c:\
c:\$ But I agree that |
|
@tniessen It might be helpful to look at what other platforms are doing. Python 3.5.3 does: >>> import ntpath
>>> ntpath.normpath('C:')
'C:'
>>> ntpath.normpath('C:.')
'C:'
>>> ntpath.normpath('C:\\')
'C:\\'
>>> ntpath.normpath('C:\\abc')
'C:\\abc'
>>> ntpath.normpath('C:abc')
'C:abc'
>>>
>>> ntpath.join('C:')
'C:'
>>> ntpath.join('C:\\')
'C:\\'
>>> ntpath.join('C:', '.')
'C:.'
>>> ntpath.join('C:', 'abc')
'C:abc'
>>> ntpath.join('C:\\', 'abc')
'C:\\abc'
>>> ntpath.join('C:\\abc', '.')
'C:\\abc\\.' From what I'm reading in this thread, the About { root: 'C:', dir: '', base: '.', ext: '', name: '.' }
not { root: 'C:', dir: '', base: 'C:.', ext: '', name: 'C:.' } (current) The By the same logic { root: 'C:', dir: '', base: 'abc', ext: '', name: 'abc' }
not { root: 'C:', dir: '', base: 'C:abc', ext: '', name: 'C:abc' } (current) |
Here's the Python equivalent for >>> from pathlib import PureWindowsPath
>>> def PrintPath(p):
... print({ 'drive': p.drive, 'root': p.root, 'anchor': p.anchor, 'parent': p.parent, 'name': p.name })
...
>>> PrintPath(PureWindowsPath('C:abc'))
{'drive': 'C:', 'anchor': 'C:', 'parent': PureWindowsPath('C:'), 'name': 'abc', 'root': ''}
>>> PrintPath(PureWindowsPath('C:\\abc'))
{'drive': 'C:', 'anchor': 'C:\\', 'parent': PureWindowsPath('C:/'), 'name': 'abc', 'root': '\\'}
>>> PrintPath(PureWindowsPath('C:.'))
{'drive': 'C:', 'anchor': 'C:', 'parent': PureWindowsPath('C:'), 'name': '', 'root': ''}
|
Yes, it is correct, but I am not entirely sure we should prefer that over @TimothyGu Sounds good. Your interpretation of Currently, the only platform-dependent functions are the
In my opinion, this is our best shot at a compromise between correctness and platform-independentness. This behavior will need to be documented precisely. For the vast majority of users, this won't change anything. I hope to get some time within the next days to propose a solution to some of these problems. |
There's also my suggested #13887 (comment) opt-in way, either: const path = require('path');
path.strict.posix.resolve('.\\gaga') // throws
const { strict: spath } = path;
spath.posix.resolve('.\\gaga') // throws or const { Pure } = require('path');
const purePath1 = new Pure('C:\\fakepath')
purePath1.resolve('gaga') === 'C:\\fakepath\\gaga';
const purePath2 = new Pure();
purePath1.resolve('gaga') === Pure.resolve('gaga') // throws or returns just 'gaga' |
@tniessen This issue is about path normalization (which doesn't depend on the local file system), not resolution. |
@TimothyGu I know, I just thought the other problems were related enough to bring them up here. Sure, this issue can be solved independently. |
@TimothyGu According to our documentation, |
@tniessen Cool. I'll implement this in an upcoming PR. |
I just opened #14440 after auditing all |
`path.resolve()` and `path.join()` are left alone in this commit due to the lack of clear semantics. Fixes: nodejs#14405
@XGHeaven Thank you for your report, @TimothyGu fixed the behavior of the |
@TimothyGu Thanks. I have a question about if this bug fixed in LTS? I remember this bug just fixed in master. |
Backporting to release lines can take some time. cc @nodejs/lts |
@XGHeaven This will be considered in the next v6.x release. If 2791761 cherry-picks cleanly to v6.x, and the risk of the change is deemed to be low, it should go into the next release. If it doesn't cherry-pick cleanly it'll have to be backported (process here). v4.x is in maintenance, so most fixes aren't backported. I suggest you subscribe to #14440, any discussion about backporting to v6.x will happen on there. |
`path.resolve()` and `path.join()` are left alone in this commit due to the lack of clear semantics. PR-URL: nodejs/node#14440 Fixes: nodejs/node#14405 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
In windows,
path.join('C:')
return 'C:.' not 'C:'In other system, such as linux,macos always return 'C:'
In windows, 'path.join('C:\')' is corrrect, return 'C:\'
But you give path.join more than one args, it's correct.
such as
path.join('C:', 'a')
== 'C:\a'here is a interesting thing, if you run
path.format(path.parse(path.join('C:')))
in windows,returns 'C:C:.'
I don't know why...
The text was updated successfully, but these errors were encountered: