-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
fs: create consistent behavior for fs module across platforms #17927
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1365,13 +1365,16 @@ function getPathFromURLPosix(url) { | |
| return decodeURIComponent(pathname); | ||
| } | ||
|
|
||
| function getPathFromURL(path) { | ||
| function getPathFromURL(path, assertFilename) { | ||
| if (path == null || !path[searchParams] || | ||
| !path[searchParams][searchParams]) { | ||
| return path; | ||
| } | ||
| if (path.protocol !== 'file:') | ||
| throw new errors.TypeError('ERR_INVALID_URL_SCHEME', 'file'); | ||
|
|
||
| if (assertFilename && path.href[path.href.length - 1] === '/') | ||
| throw new errors.Error('ERR_PATH_IS_DIRECTORY', 'path', path.pathname); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The string being checked and reported here should be the result of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or, maybe |
||
| return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,206 @@ | ||
| 'use strict'; | ||
|
|
||
| const common = require('../common'); | ||
| const fs = require('fs'); | ||
| const URL = require('url').URL; | ||
| const util = require('util'); | ||
|
|
||
| function runPathTests(withSlash, withoutSlash, slashedPath, realName) { | ||
|
|
||
| if (!slashedPath) { | ||
| slashedPath = withSlash; | ||
| } else if (typeof slashedPath === 'boolean') { | ||
| realName = slashedPath; | ||
| slashedPath = withSlash; | ||
| } | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.readFile(withSlash, common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.readFileSync(withSlash, { flag: 'r' }); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.open(withSlash, 'r', common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.openSync(withSlash, 'r'); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.appendFile(withSlash, 'test data', common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.appendFileSync(withSlash, 'test data'); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.createReadStream(withSlash); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.createWriteStream(withSlash); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.truncate(withSlash, 4, common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.truncateSync(withSlash, 4); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.writeFile(withSlash, 'test data', common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.writeFileSync(withSlash, 'test data'); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: 'The argument "path" must not end with "/". ' + | ||
| `Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.copyFile(withSlash, withoutSlash, common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: `The argument "${realName ? 'src' : 'path'}" must not end ` + | ||
| `with "/". Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.copyFile(withoutSlash, withSlash, common.mustNotCall()); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: `The argument "${realName ? 'dest' : 'path'}" must not end ` + | ||
| `with "/". Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.copyFileSync(withSlash, withoutSlash); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: `The argument "${realName ? 'src' : 'path'}" must not end ` + | ||
| `with "/". Received ${util.inspect(slashedPath)}` | ||
| }); | ||
|
|
||
| common.expectsError( | ||
| () => { | ||
| fs.copyFileSync(withoutSlash, withSlash); | ||
| }, | ||
| { | ||
| code: 'ERR_PATH_IS_DIRECTORY', | ||
| type: Error, | ||
| message: `The argument "${realName ? 'dest' : 'path'}" must not end ` + | ||
| `with "/". Received ${util.inspect(slashedPath)}` | ||
| }); | ||
| } | ||
|
|
||
| const path = '/tmp/test'; | ||
| const stringWithSlash = common.isWindows ? `file:///c:${path}/` : | ||
| `file://${path}/`; | ||
| const stringWithoutSlash = common.isWindows ? `file:///c:${path}` : | ||
| `file://${path}`; | ||
| const urlWithSlash = new URL(stringWithSlash); | ||
| const urlWithoutSlash = new URL(stringWithoutSlash); | ||
| const U8ABufferWithSlash = new Uint8Array(Buffer.from(stringWithSlash)); | ||
| const U8ABufferWithoutSlash = new Uint8Array(Buffer.from(stringWithoutSlash)); | ||
| runPathTests(urlWithSlash, urlWithoutSlash, `${path}/`); | ||
| runPathTests(stringWithSlash, stringWithoutSlash, true); | ||
| runPathTests(U8ABufferWithSlash, U8ABufferWithoutSlash, true); |
Uh oh!
There was an error while loading. Please reload this page.
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.
There is already one
this.path = getPathFromURL(path);below. Alsopathis ignored ifoptions.fd !== undefinedso maybe we just need to delete this and change the line below to:Same about
ReadStreamUh oh!
There was an error while loading. Please reload this page.
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.
validatePathonly acceptsUint8Arraythis will work if Stream path is alwaysUint8Arrayorstring.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.
@timotew The path in the fs stream classes can be falsy if
options.fdis provdided, e.g.fs.createReadStream(null, { fd: fd, encoding: 'utf8' })is valid. From what I can tell,validatePathaccepts bothstringandUint8Array.