-
Notifications
You must be signed in to change notification settings - Fork 30k
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
fs,doc,test: open reserved characters under win32 #13875
fs,doc,test: open reserved characters under win32 #13875
Conversation
lib/fs.js
Outdated
if (longPath.indexOf(':', 6) !== -1) { | ||
const err = new errors.Error('ERR_INVALID_WIN32_PATH', longPath); | ||
if (req) { | ||
return process.nextTick(function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this extra closure is needed. Perhaps it could just be process.nextTick(req.oncomplete, err)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mscdex sometimes req.oncomplete
depends on req
, eg.
var context = new ReadFileContext(callback, options.encoding);
context.isUserFd = isFd(path); // file descriptor ownership
var req = new FSReqWrap();
req.context = context;
req.oncomplete = readFileAfterOpen;
...
function readFileAfterOpen(err, fd) {
var context = this.context;
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Perhaps we could at least factor out the callback then, like:
process.nextTick(onWinOpenErrorNT, req, err);
// ...
function onWinOpenErrorNT(req, err) {
req.oncomplete(err);
}
I wonder if having two separate implementations, one for posix and one for Windows, would help any performance-wise? I think it definitely would on node v6.x, which still uses Crankshaft and would possibly allow the posix version to be inlineable. |
@mscdex Now only one call stack is added, and an |
lib/fs.js
Outdated
if (isWindows) { | ||
// \\?\c:\somepath\1:path | ||
// \\?\UNC\somepath\2:path | ||
if (longPath.indexOf(':', 6) !== -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to start explicitly checking for these, perhaps we should be checking for all of the reserved characters, either here in JS or at the libuv layer (via a flag of some kind if not enforced all the time for Windows).
EDIT: I just saw your comment about the other reserved characters. I'm wondering if we actually test for those on Windows nodes in CI...
Did you test other invalid characters and/or filenames (like https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#Naming_Conventions |
I will try it tomorrow, now it's 1:11 a.m. at my location and I'm going to sleep. |
@mscdex @silverwind Sorry, I'm going to take a vacation for one week and now I don't have a Windows computer at my hand. So maybe I will continue to work for this PR after one week. |
lib/fs.js
Outdated
stringToFlags(options.flag || 'r'), | ||
0o666, | ||
req); | ||
openWrap(path, stringToFlags(options.flags || 'r'), 0o666, req); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the stringToFlags()
calls should be pushed into openWrap()
too.
lib/fs.js
Outdated
// \\?\UNC\somepath\2:path | ||
if (longPath.indexOf(':', 6) !== -1) { | ||
const err = new errors.Error('ERR_INVALID_WIN32_PATH', longPath); | ||
if (req) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: single line if
statements shouldn't have curly braces.
lib/internal/errors.js
Outdated
@@ -187,6 +187,7 @@ E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536'); | |||
E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running'); | |||
E('ERR_V8BREAKITERATOR', 'full ICU data not installed. ' + | |||
'See https://github.com/nodejs/node/wiki/Intl'); | |||
E('ERR_INVALID_WIN32_PATH', (path) => `Invalid path under win32: '${path}'`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the errors in this file are sorted by error code.
@@ -0,0 +1,76 @@ | |||
// Copyright Joyent, Inc. and other Node contributors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you have to add this for new files.
|
||
const isWindows = process.platform === 'win32'; | ||
|
||
if (!isWindows) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use common.skip()
here.
}); | ||
|
||
OK.forEach((path) => { | ||
fs.writeFile(path, 'world', { encoding: 'utf8' }, function(err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add common.mustCall()
to the readFile()
and writeFile()
callbacks in this file.
|
||
FAIL.forEach((path) => { | ||
fs.readFile(path, { encoding: 'utf8' }, function(err) { | ||
assert.ok(/Invalid path under win32/.test(err.message)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use ^
and $
to match the full error message.
I agree with @mscdex, if we do this checking, it's better done in libuv. Of course, it's also possible to delegate the task of checking if a filename is valid for a platform to the user, for example through modules like https://github.com/sindresorhus/valid-filename. |
@silverwind To be honest, I think libuv's PR progress is much slower than Node.js'. I will continue to work for other reserved names by implement a checking function next week after my vacation. |
Enjoy 🍹 |
This |
Oh, forgot to add that I'm -1 on this. |
@bzoz It has an element of surprise (alternative streams I personally keep forgetting about). Should we at least document this? Or maybe add special syntax for? |
IMHO we should document this. Special syntax would be surprising for everyone that already knows this feature. It would also add maintenance burden. |
@bzoz so what I should do is just to document it? |
I guess so. The streams feature of NTFS is surprising, we can mention it in the docs and add a link to MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/bb540537.aspx |
I'll update this issue to document this feature after I'm back. |
9498ec8
to
e90f5cb
Compare
86dc587
to
c1c5d57
Compare
Explain the behavior of
fs.open()
under win32 that file path containssome characters and add some test cases for them.
Refs: #13868
Refs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
Refs: https://msdn.microsoft.com/en-us/library/windows/desktop/bb540537.aspx
Checklist
make -j4 test
(UNIX)Affected core subsystem(s)
fs, doc, test