Closed
Description
- Version: v8.1.1
- Platform: Windows 10
- Subsystem: path
path.posix.resolve
, path.posix.relative
return wrong path on Windows.
For example:
path.posix.resolve('a/b/c'); // returns: 'C:\\Users\\fei\\Desktop\\share\\node/a/b/c'
Ref: #13683
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
DuanPengfei commentedon Jun 23, 2017
Hope I can find a good way to fix it. 😂
refack commentedon Jun 23, 2017
I had an idea, add a new "strict mode" to
path
:seishun commentedon Jun 23, 2017
Can you clarify why it's wrong?
refack commentedon Jun 23, 2017
The result is not a valid path nor on windows (the host) and definitely not on POSIX (the expected target).
The root cause is that
resolve
usesprocess.cwd()
which is the only point where thepath
module does something that is not pure string manipulation.See discussion at: #13683 (comment)
tniessen commentedon Jun 24, 2017
I am against introducing a strict mode. Instead, I would prefer to always throw if
process.cwd()
needs to be used and the host platform is not the same as the API platform. If we care about breakage too much, we can introduce a deprecation cycle such thatpath.posix.resolve
andpath.win32.resolve
will print warnings instead of throwing.I could put together a PR if this gets approval.
refack commentedon Jun 24, 2017
@tniessen I had the same opinion, but @mscdex and @addaleax are strongly against. The point they both raised is that this is not strictly a bug but a weird behavior that people are used to, and throwing will block "valid" code paths. With that in mind,
strict
mode would allow us in the future change the default behavior while allowing opting-out by settingpath.strict = false;
tniessen commentedon Jun 24, 2017
Introducing a global setting for such a "strict mode" sounds like an unnecessary side effect to me (unless you want to make that setting per module or similar), e.g. if an application enables strict mode and a dependency expects non-strict mode or vice versa. If you really want to implement different modes, I would suggest
require('path').strict()
.I would like to include @addaleax in this discussion so we don't have to split it and continue parts of it in #13683.
Let's look at something simple:
So what would be the "correct result" on Windows? Let's say
process.cwd()
isF:\node
. Would you expectF:\node/foo/bar
? Not a good idea, it is not a valid posix path. How aboutF:/node/foo/bar
? Looks good, butresolve
must return an absolute path, andpath.posix.isAbsolute('F:/node/foo/bar')
isfalse
, and there is no way to change that, as this is a relative path on posix systems. How about/F:/node/foo/bar
? Too bad, now it is not even a valid path on Windows anymore.XadillaX commentedon Jun 24, 2017
how about starting a vote?
addaleax commentedon Jun 24, 2017
I also really don’t like the idea of strict mode; all
path
functions currently are pure, up to their dependency oncwd()
, and that’s a good thing. If you want it, add an extra parameter or add new methods, don’t introduce global mutable state.Re: always throwing when
process.cwd()
is used… people are doing weird stuff withpath
, and the thing is, the end result isn’t always dependent on all of the input. For example, one could usepath.resolve()
on two different paths, where the cwd may or may not be used, and then callpath.relative()
and get a result that doesn’t actually depend on the cwd or only parts of it, even though the intermediate results do.It’s a nice thing that explicit
path.posix.resolve()
is likely used much less frequently than justpath.resolve()
; but I am afraid users might just use that e.g. if they need URL-like paths for some reason, or basically just “want to get forward slashes” for any possible reason, rather than using the Windows method and then fixing up the result to fit their format.I would accept that; it’s strictly better than the current state of things, and even though
path.posix.isAbsolute('F:/node/foo/bar')
returnsfalse
, it is still an absolute path for all other purposes.Our process is consensus-seeking, so usually things don’t work that way; we’ll keep discussing the issue (and maybe coming up with new solutions) until we either reach consensus or it becomes clear that we won’t reach consensus. I don’t think we’re at either point yet.
If we won’t be able to get consensus, we’ll likely put this on the CTC meeting agenda, where it will be discussed, and we’ll only vote if the CTC won’t get consensus either. I think it’s unlikely that it will come to that.
tniessen commentedon Jun 25, 2017
Definitely +1!
Good point, we might need to come up with a better solution.
Then let's have a look at
path.posix.resolve(process.cwd(), 'foo')
. Everything is fine when executed under linux, but it will return something like'F:\\node/F:\\node/foo'
on Windows, and there is no way to change that, because the posix API considers the result ofprocess.cwd()
relative.Sure, you could say that it does not make sense to do this, using a Windows API call with the posix API... But that's exactly what we are doing in the current
path
module.If we decide not to throw an
Error
in these situations, we should at least add notes to the docs explaining the current behavior (after fixing bugs as in #13683).refack commentedon Jun 25, 2017
Offf I forgot about the globalness of modules... How about something like...
Again it's opt-in, and gives us a path to deprecation with explicit and opt-out in the future.
refack commentedon Jun 25, 2017
Another idea: an implementation that's pure strings, with an optional
cwd
as arg[refack: tweaked code]
DuanPengfei commentedon Jun 25, 2017
I also prefer the pure function, but if this is done, does it mean that the history code needs to be modified?
21 remaining items