Skip to content
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: improve mode and flags validation #27044

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 57 additions & 71 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1556,14 +1556,14 @@ Returns an object containing commonly used constants for file system
operations. The specific constants currently defined are described in
[FS Constants][].

## `fs.copyFile(src, dest[, flags], callback)`
## `fs.copyFile(src, dest[, mode], callback)`
<!-- YAML
added: v8.5.0
-->

* `src` {string|Buffer|URL} source filename to copy
* `dest` {string|Buffer|URL} destination filename of the copy operation
* `flags` {number} modifiers for copy operation. **Default:** `0`.
* `mode` {integer} modifiers for copy operation. **Default:** `0`.
* `callback` {Function}

Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it
Expand All @@ -1572,7 +1572,7 @@ callback function. Node.js makes no guarantees about the atomicity of the copy
operation. If an error occurs after the destination file has been opened for
writing, Node.js will attempt to remove the destination.

`flags` is an optional integer that specifies the behavior
`mode` is an optional integer that specifies the behavior
of the copy operation. It is possible to create a mask consisting of the bitwise
OR of two or more values (e.g.
`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`).
Expand All @@ -1588,39 +1588,35 @@ then the operation will fail.

```js
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;

// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', (err) => {
function callback(err) {
if (err) throw err;
console.log('source.txt was copied to destination.txt');
});
```

If the third argument is a number, then it specifies `flags`:
}

```js
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;
// destination.txt will be created or overwritten by default.
fs.copyFile('source.txt', 'destination.txt', callback);

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
fs.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL, callback);
```

## `fs.copyFileSync(src, dest[, flags])`
## `fs.copyFileSync(src, dest[, mode])`
<!-- YAML
added: v8.5.0
-->

* `src` {string|Buffer|URL} source filename to copy
* `dest` {string|Buffer|URL} destination filename of the copy operation
* `flags` {number} modifiers for copy operation. **Default:** `0`.
* `mode` {integer} modifiers for copy operation. **Default:** `0`.

Synchronously copies `src` to `dest`. By default, `dest` is overwritten if it
already exists. Returns `undefined`. Node.js makes no guarantees about the
atomicity of the copy operation. If an error occurs after the destination file
has been opened for writing, Node.js will attempt to remove the destination.

`flags` is an optional integer that specifies the behavior
`mode` is an optional integer that specifies the behavior
of the copy operation. It is possible to create a mask consisting of the bitwise
OR of two or more values (e.g.
`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`).
Expand All @@ -1636,17 +1632,11 @@ then the operation will fail.

```js
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;

// destination.txt will be created or overwritten by default.
fs.copyFileSync('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');
```

If the third argument is a number, then it specifies `flags`:

```js
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
fs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL);
Expand Down Expand Up @@ -1796,12 +1786,11 @@ changes:
* `fs` {Object|null} **Default:** `null`
* Returns: {fs.WriteStream} See [Writable Stream][].

`options` may also include a `start` option to allow writing data at
some position past the beginning of the file, allowed values are in the
[0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather
than replacing it may require a `flags` mode of `r+` rather than the
default mode `w`. The `encoding` can be any one of those accepted by
[`Buffer`][].
`options` may also include a `start` option to allow writing data at some
position past the beginning of the file, allowed values are in the
[0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather than replacing
it may require the `flags` option to be set to `r+` rather than the default `w`.
The `encoding` can be any one of those accepted by [`Buffer`][].

If `autoClose` is set to true (default behavior) on `'error'` or `'finish'`
the file descriptor will be closed automatically. If `autoClose` is false,
Expand Down Expand Up @@ -2466,7 +2455,7 @@ changes:
Asynchronously creates a directory. No arguments other than a possible exception
are given to the completion callback.

The optional `options` argument can be an integer specifying mode (permission
The optional `options` argument can be an integer specifying `mode` (permission
and sticky bits), or an object with a `mode` property and a `recursive`
property indicating whether parent folders should be created. Calling
`fs.mkdir()` when `path` is a directory that exists results in an error only
Expand Down Expand Up @@ -2617,7 +2606,7 @@ changes:
description: The `flags` argument is now optional and defaults to `'r'`.
- version: v9.9.0
pr-url: https://github.com/nodejs/node/pull/18801
description: The `as` and `as+` modes are supported now.
description: The `as` and `as+` flags are supported now.
- version: v7.6.0
pr-url: https://github.com/nodejs/node/pull/10739
description: The `path` parameter can be a WHATWG `URL` object using `file:`
Expand Down Expand Up @@ -2709,7 +2698,7 @@ changes:
description: The `flags` argument is now optional and defaults to `'r'`.
- version: v9.9.0
pr-url: https://github.com/nodejs/node/pull/18801
description: The `as` and `as+` modes are supported now.
description: The `as` and `as+` flags are supported now.
- version: v7.6.0
pr-url: https://github.com/nodejs/node/pull/10739
description: The `path` parameter can be a WHATWG `URL` object using `file:`
Expand Down Expand Up @@ -3276,16 +3265,16 @@ changes:
* `path` {string|Buffer|URL}
* `options` {Object}
* `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents the
number of retries. This option is ignored if the `recursive` option is not
`true`. **Default:** `0`.
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents
the number of retries. This option is ignored if the `recursive` option is
not `true`. **Default:** `0`.
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
* `retryDelay` {integer} The amount of time in milliseconds to wait between
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.
* `callback` {Function}
* `err` {Error}

Expand Down Expand Up @@ -3321,16 +3310,16 @@ changes:
* `path` {string|Buffer|URL}
* `options` {Object}
* `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents the
number of retries. This option is ignored if the `recursive` option is not
`true`. **Default:** `0`.
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents
the number of retries. This option is ignored if the `recursive` option is
not `true`. **Default:** `0`.
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
* `retryDelay` {integer} The amount of time in milliseconds to wait between
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.

Synchronous rmdir(2). Returns `undefined`.

Expand Down Expand Up @@ -4687,14 +4676,14 @@ added: v10.0.0
Changes the ownership of a file then resolves the `Promise` with no arguments
upon success.

### `fsPromises.copyFile(src, dest[, flags])`
### `fsPromises.copyFile(src, dest[, mode])`
<!-- YAML
added: v10.0.0
-->

* `src` {string|Buffer|URL} source filename to copy
* `dest` {string|Buffer|URL} destination filename of the copy operation
* `flags` {number} modifiers for copy operation. **Default:** `0`.
* `mode` {integer} modifiers for copy operation. **Default:** `0`.
* Returns: {Promise}

Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it
Expand All @@ -4704,7 +4693,7 @@ Node.js makes no guarantees about the atomicity of the copy operation. If an
error occurs after the destination file has been opened for writing, Node.js
will attempt to remove the destination.

`flags` is an optional integer that specifies the behavior
`mode` is an optional integer that specifies the behavior
of the copy operation. It is possible to create a mask consisting of the bitwise
OR of two or more values (e.g.
`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`).
Expand All @@ -4719,20 +4708,17 @@ create a copy-on-write reflink. If the platform does not support copy-on-write,
then the operation will fail.

```js
const fsPromises = require('fs').promises;
const {
promises: fsPromises,
constants: {
COPYFILE_EXCL
}
} = require('fs');

// destination.txt will be created or overwritten by default.
fsPromises.copyFile('source.txt', 'destination.txt')
.then(() => console.log('source.txt was copied to destination.txt'))
.catch(() => console.log('The file could not be copied'));
```

If the third argument is a number, then it specifies `flags`:

```js
const fs = require('fs');
const fsPromises = fs.promises;
const { COPYFILE_EXCL } = fs.constants;

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL)
Expand Down Expand Up @@ -4813,7 +4799,7 @@ added: v10.0.0
Asynchronously creates a directory then resolves the `Promise` with no
arguments upon success.

The optional `options` argument can be an integer specifying mode (permission
The optional `options` argument can be an integer specifying `mode` (permission
and sticky bits), or an object with a `mode` property and a `recursive`
property indicating whether parent folders should be created. Calling
`fsPromises.mkdir()` when `path` is a directory that exists results in a
Expand Down Expand Up @@ -5044,16 +5030,16 @@ changes:
* `path` {string|Buffer|URL}
* `options` {Object}
* `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents the
number of retries. This option is ignored if the `recursive` option is not
`true`. **Default:** `0`.
`EPERM` error is encountered, Node.js will retry the operation with a linear
backoff wait of `retryDelay` ms longer on each try. This option represents
the number of retries. This option is ignored if the `recursive` option is
not `true`. **Default:** `0`.
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
recursive mode, errors are not reported if `path` does not exist, and
operations are retried on failure. **Default:** `false`.
* `retryDelay` {integer} The amount of time in milliseconds to wait between
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.
retries. This option is ignored if the `recursive` option is not `true`.
**Default:** `100`.
* Returns: {Promise}

Removes the directory identified by `path` then resolves the `Promise` with
Expand Down Expand Up @@ -5494,8 +5480,8 @@ On Linux, positional writes don't work when the file is opened in append mode.
The kernel ignores the position argument and always appends the data to
the end of the file.

Modifying a file rather than replacing it may require a flags mode of `'r+'`
rather than the default mode `'w'`.
Modifying a file rather than replacing it may require the `flag` option to be
set to `'r+'` rather than the default `'w'`.

The behavior of some flags are platform-specific. As such, opening a directory
on macOS and Linux with the `'a+'` flag, as in the example below, will return an
Expand Down Expand Up @@ -5541,7 +5527,7 @@ the file contents.
[`fs.access()`]: #fs_fs_access_path_mode_callback
[`fs.chmod()`]: #fs_fs_chmod_path_mode_callback
[`fs.chown()`]: #fs_fs_chown_path_uid_gid_callback
[`fs.copyFile()`]: #fs_fs_copyfile_src_dest_flags_callback
[`fs.copyFile()`]: #fs_fs_copyfile_src_dest_mode_callback
[`fs.createWriteStream()`]: #fs_fs_createwritestream_path_options
[`fs.exists()`]: fs.html#fs_fs_exists_path_callback
[`fs.fstat()`]: #fs_fs_fstat_fd_options_callback
Expand Down
Loading