Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 950a441

Browse filesBrowse files
fs: remove coercion to string in writing methods
Moves DEP0162 to End-of-Life. PR-URL: #42796 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 047cd61 commit 950a441
Copy full SHA for 950a441

File tree

Expand file treeCollapse file tree

7 files changed

+51
-91
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+51
-91
lines changed
Open diff view settings
Collapse file

‎doc/api/deprecations.md‎

Copy file name to clipboardExpand all lines: doc/api/deprecations.md
+4-1Lines changed: 4 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -3131,6 +3131,9 @@ resources and not the actual references.
31313131

31323132
<!-- YAML
31333133
changes:
3134+
- version: REPLACEME
3135+
pr-url: https://github.com/nodejs/node/pull/42796
3136+
description: End-of-Life.
31343137
- version: v18.0.0
31353138
pr-url: https://github.com/nodejs/node/pull/42607
31363139
description: Runtime deprecation.
@@ -3141,7 +3144,7 @@ changes:
31413144
description: Documentation-only deprecation.
31423145
-->
31433146

3144-
Type: Runtime
3147+
Type: End-of-Life
31453148

31463149
Implicit coercion of objects with own `toString` property, passed as second
31473150
parameter in [`fs.write()`][], [`fs.writeFile()`][], [`fs.appendFile()`][],
Collapse file

‎doc/api/fs.md‎

Copy file name to clipboardExpand all lines: doc/api/fs.md
+17-5Lines changed: 17 additions & 5 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -4534,6 +4534,10 @@ default with the above values.
45344534
<!-- YAML
45354535
added: v0.11.5
45364536
changes:
4537+
- version: REPLACEME
4538+
pr-url: https://github.com/nodejs/node/pull/42796
4539+
description: Passing to the `string` parameter an object with an own
4540+
`toString` function is no longer supported.
45374541
- version: v17.8.0
45384542
pr-url: https://github.com/nodejs/node/pull/42149
45394543
description: Passing to the `string` parameter an object with an own
@@ -4560,16 +4564,16 @@ changes:
45604564
-->
45614565

45624566
* `fd` {integer}
4563-
* `string` {string|Object}
4567+
* `string` {string}
45644568
* `position` {integer|null} **Default:** `null`
45654569
* `encoding` {string} **Default:** `'utf8'`
45664570
* `callback` {Function}
45674571
* `err` {Error}
45684572
* `written` {integer}
45694573
* `string` {string}
45704574

4571-
Write `string` to the file specified by `fd`. If `string` is not a string, or an
4572-
object with an own `toString` function property, then an exception is thrown.
4575+
Write `string` to the file specified by `fd`. If `string` is not a string,
4576+
an exception is thrown.
45734577

45744578
`position` refers to the offset from the beginning of the file where this data
45754579
should be written. If `typeof position !== 'number'` the data will be written at
@@ -4602,6 +4606,10 @@ details.
46024606
<!-- YAML
46034607
added: v0.1.29
46044608
changes:
4609+
- version: REPLACEME
4610+
pr-url: https://github.com/nodejs/node/pull/42796
4611+
description: Passing to the `string` parameter an object with an own
4612+
`toString` function is no longer supported.
46054613
- version: v18.0.0
46064614
pr-url: https://github.com/nodejs/node/pull/41678
46074615
description: Passing an invalid callback to the `callback` argument
@@ -4650,7 +4658,7 @@ changes:
46504658
-->
46514659

46524660
* `file` {string|Buffer|URL|integer} filename or file descriptor
4653-
* `data` {string|Buffer|TypedArray|DataView|Object}
4661+
* `data` {string|Buffer|TypedArray|DataView}
46544662
* `options` {Object|string}
46554663
* `encoding` {string|null} **Default:** `'utf8'`
46564664
* `mode` {integer} **Default:** `0o666`
@@ -5840,6 +5848,10 @@ this API: [`fs.utimes()`][].
58405848
<!-- YAML
58415849
added: v0.1.29
58425850
changes:
5851+
- version: REPLACEME
5852+
pr-url: https://github.com/nodejs/node/pull/42796
5853+
description: Passing to the `data` parameter an object with an own
5854+
`toString` function is no longer supported.
58435855
- version: v17.8.0
58445856
pr-url: https://github.com/nodejs/node/pull/42149
58455857
description: Passing to the `data` parameter an object with an own
@@ -5865,7 +5877,7 @@ changes:
58655877
-->
58665878

58675879
* `file` {string|Buffer|URL|integer} filename or file descriptor
5868-
* `data` {string|Buffer|TypedArray|DataView|Object}
5880+
* `data` {string|Buffer|TypedArray|DataView}
58695881
* `options` {Object|string}
58705882
* `encoding` {string|null} **Default:** `'utf8'`
58715883
* `mode` {integer} **Default:** `0o666`
Collapse file

‎lib/fs.js‎

Copy file name to clipboardExpand all lines: lib/fs.js
+7-24Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const {
3939
ReflectApply,
4040
SafeMap,
4141
SafeSet,
42-
String,
4342
StringPrototypeCharCodeAt,
4443
StringPrototypeIndexOf,
4544
StringPrototypeSlice,
@@ -84,7 +83,6 @@ const { FSReqCallback } = binding;
8483
const { toPathIfFileURL } = require('internal/url');
8584
const {
8685
customPromisifyArgs: kCustomPromisifyArgsSymbol,
87-
deprecate,
8886
kEmptyObject,
8987
promisify: {
9088
custom: kCustomPromisifiedSymbol,
@@ -123,7 +121,6 @@ const {
123121
validateRmOptionsSync,
124122
validateRmdirOptions,
125123
validateStringAfterArrayBufferView,
126-
validatePrimitiveStringAfterArrayBufferView,
127124
warnOnNonPortableTemplate
128125
} = require('internal/fs/utils');
129126
const {
@@ -171,11 +168,6 @@ const isWindows = process.platform === 'win32';
171168
const isOSX = process.platform === 'darwin';
172169

173170

174-
const showStringCoercionDeprecation = deprecate(
175-
() => {},
176-
'Implicit coercion of objects with own toString property is deprecated.',
177-
'DEP0162'
178-
);
179171
function showTruncateDeprecation() {
180172
if (truncateWarn) {
181173
process.emitWarning(
@@ -813,7 +805,7 @@ function readvSync(fd, buffers, position) {
813805
/**
814806
* Writes `buffer` to the specified `fd` (file descriptor).
815807
* @param {number} fd
816-
* @param {Buffer | TypedArray | DataView | string | object} buffer
808+
* @param {Buffer | TypedArray | DataView | string} buffer
817809
* @param {number | object} [offsetOrOptions]
818810
* @param {number} [length]
819811
* @param {number | null} [position]
@@ -861,9 +853,6 @@ function write(fd, buffer, offsetOrOptions, length, position, callback) {
861853
}
862854

863855
validateStringAfterArrayBufferView(buffer, 'buffer');
864-
if (typeof buffer !== 'string') {
865-
showStringCoercionDeprecation();
866-
}
867856

868857
if (typeof position !== 'function') {
869858
if (typeof offset === 'function') {
@@ -875,7 +864,7 @@ function write(fd, buffer, offsetOrOptions, length, position, callback) {
875864
length = 'utf8';
876865
}
877866

878-
const str = String(buffer);
867+
const str = buffer;
879868
validateEncoding(str, length);
880869
callback = maybeCallback(position);
881870

@@ -926,7 +915,7 @@ function writeSync(fd, buffer, offsetOrOptions, length, position) {
926915
result = binding.writeBuffer(fd, buffer, offset, length, position,
927916
undefined, ctx);
928917
} else {
929-
validatePrimitiveStringAfterArrayBufferView(buffer, 'buffer');
918+
validateStringAfterArrayBufferView(buffer, 'buffer');
930919
validateEncoding(buffer, length);
931920

932921
if (offset === undefined)
@@ -2154,7 +2143,7 @@ function writeAll(fd, isUserFd, buffer, offset, length, signal, callback) {
21542143
/**
21552144
* Asynchronously writes data to the file.
21562145
* @param {string | Buffer | URL | number} path
2157-
* @param {string | Buffer | TypedArray | DataView | object} data
2146+
* @param {string | Buffer | TypedArray | DataView} data
21582147
* @param {{
21592148
* encoding?: string | null;
21602149
* mode?: number;
@@ -2171,10 +2160,7 @@ function writeFile(path, data, options, callback) {
21712160

21722161
if (!isArrayBufferView(data)) {
21732162
validateStringAfterArrayBufferView(data, 'data');
2174-
if (typeof data !== 'string') {
2175-
showStringCoercionDeprecation();
2176-
}
2177-
data = Buffer.from(String(data), options.encoding || 'utf8');
2163+
data = Buffer.from(data, options.encoding || 'utf8');
21782164
}
21792165

21802166
if (isFd(path)) {
@@ -2201,7 +2187,7 @@ function writeFile(path, data, options, callback) {
22012187
/**
22022188
* Synchronously writes data to the file.
22032189
* @param {string | Buffer | URL | number} path
2204-
* @param {string | Buffer | TypedArray | DataView | object} data
2190+
* @param {string | Buffer | TypedArray | DataView} data
22052191
* @param {{
22062192
* encoding?: string | null;
22072193
* mode?: number;
@@ -2214,10 +2200,7 @@ function writeFileSync(path, data, options) {
22142200

22152201
if (!isArrayBufferView(data)) {
22162202
validateStringAfterArrayBufferView(data, 'data');
2217-
if (typeof data !== 'string') {
2218-
showStringCoercionDeprecation();
2219-
}
2220-
data = Buffer.from(String(data), options.encoding || 'utf8');
2203+
data = Buffer.from(data, options.encoding || 'utf8');
22212204
}
22222205

22232206
const flag = options.flag || 'w';
Collapse file

‎lib/internal/fs/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/promises.js
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const {
6666
validateOffsetLengthWrite,
6767
validateRmOptions,
6868
validateRmdirOptions,
69-
validatePrimitiveStringAfterArrayBufferView,
69+
validateStringAfterArrayBufferView,
7070
warnOnNonPortableTemplate,
7171
} = require('internal/fs/utils');
7272
const { opendir } = require('internal/fs/dir');
@@ -608,7 +608,7 @@ async function write(handle, buffer, offsetOrOptions, length, position) {
608608
return { bytesWritten, buffer };
609609
}
610610

611-
validatePrimitiveStringAfterArrayBufferView(buffer, 'buffer');
611+
validateStringAfterArrayBufferView(buffer, 'buffer');
612612
validateEncoding(buffer, length);
613613
const bytesWritten = (await binding.writeString(handle.fd, buffer, offset,
614614
length, kUsePromises)) || 0;
@@ -838,7 +838,7 @@ async function writeFile(path, data, options) {
838838
const flag = options.flag || 'w';
839839

840840
if (!isArrayBufferView(data) && !isCustomIterable(data)) {
841-
validatePrimitiveStringAfterArrayBufferView(data, 'data');
841+
validateStringAfterArrayBufferView(data, 'data');
842842
data = Buffer.from(data, options.encoding || 'utf8');
843843
}
844844

Collapse file

‎lib/internal/fs/utils.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/utils.js
-23Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const {
1414
MathMin,
1515
MathRound,
1616
ObjectIs,
17-
ObjectPrototypeHasOwnProperty,
1817
ObjectSetPrototypeOf,
1918
ReflectApply,
2019
ReflectOwnKeys,
@@ -874,27 +873,6 @@ const getValidMode = hideStackFrames((mode, type) => {
874873
});
875874

876875
const validateStringAfterArrayBufferView = hideStackFrames((buffer, name) => {
877-
if (typeof buffer === 'string') {
878-
return;
879-
}
880-
881-
if (
882-
typeof buffer === 'object' &&
883-
buffer !== null &&
884-
typeof buffer.toString === 'function' &&
885-
ObjectPrototypeHasOwnProperty(buffer, 'toString')
886-
) {
887-
return;
888-
}
889-
890-
throw new ERR_INVALID_ARG_TYPE(
891-
name,
892-
['string', 'Buffer', 'TypedArray', 'DataView'],
893-
buffer
894-
);
895-
});
896-
897-
const validatePrimitiveStringAfterArrayBufferView = hideStackFrames((buffer, name) => {
898876
if (typeof buffer !== 'string') {
899877
throw new ERR_INVALID_ARG_TYPE(
900878
name,
@@ -958,6 +936,5 @@ module.exports = {
958936
validateRmOptionsSync,
959937
validateRmdirOptions,
960938
validateStringAfterArrayBufferView,
961-
validatePrimitiveStringAfterArrayBufferView,
962939
warnOnNonPortableTemplate
963940
};
Collapse file

‎test/parallel/test-fs-write-file-sync.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-fs-write-file-sync.js
+15-15Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,20 @@ tmpdir.refresh();
102102
assert.strictEqual(content, 'hello world!');
103103
}
104104

105-
// Test writeFileSync with an object with an own toString function
105+
// Test writeFileSync with an invalid input
106106
{
107-
// Runtime deprecated by DEP0162
108-
common.expectWarning('DeprecationWarning',
109-
'Implicit coercion of objects with own toString property is deprecated.',
110-
'DEP0162');
111-
const file = path.join(tmpdir.path, 'testWriteFileSyncStringify.txt');
112-
const data = {
113-
toString() {
114-
return 'hello world!';
115-
}
116-
};
117-
118-
fs.writeFileSync(file, data, { encoding: 'utf8', flag: 'a' });
119-
const content = fs.readFileSync(file, { encoding: 'utf8' });
120-
assert.strictEqual(content, String(data));
107+
const file = path.join(tmpdir.path, 'testWriteFileSyncInvalid.txt');
108+
for (const data of [
109+
false, 5, {}, [], null, undefined, true, 5n, () => {}, Symbol(), new Map(),
110+
new String('notPrimitive'),
111+
{ [Symbol.toPrimitive]: (hint) => 'amObject' },
112+
{ toString() { return 'amObject'; } },
113+
Promise.resolve('amPromise'),
114+
common.mustNotCall(),
115+
]) {
116+
assert.throws(
117+
() => fs.writeFileSync(file, data, { encoding: 'utf8', flag: 'a' }),
118+
{ code: 'ERR_INVALID_ARG_TYPE' }
119+
);
120+
}
121121
}
Collapse file

‎test/parallel/test-fs-write.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-fs-write.js
+5-20Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ const fn = path.join(tmpdir.path, 'write.txt');
3333
const fn2 = path.join(tmpdir.path, 'write2.txt');
3434
const fn3 = path.join(tmpdir.path, 'write3.txt');
3535
const fn4 = path.join(tmpdir.path, 'write4.txt');
36-
const fn5 = path.join(tmpdir.path, 'write5.txt');
3736
const expected = 'ümlaut.';
3837
const constants = fs.constants;
3938

@@ -127,23 +126,6 @@ fs.open(fn3, 'w', 0o644, common.mustSucceed((fd) => {
127126
}));
128127

129128

130-
// Test write with an object with an own toString function
131-
// Runtime deprecated by DEP0162
132-
common.expectWarning('DeprecationWarning',
133-
'Implicit coercion of objects with own toString property is deprecated.',
134-
'DEP0162');
135-
fs.open(fn4, 'w', 0o644, common.mustSucceed((fd) => {
136-
const done = common.mustSucceed((written) => {
137-
assert.strictEqual(written, Buffer.byteLength(expected));
138-
fs.closeSync(fd);
139-
});
140-
141-
const data = {
142-
toString() { return expected; }
143-
};
144-
fs.write(fd, data, done);
145-
}));
146-
147129
[false, 'test', {}, [], null, undefined].forEach((i) => {
148130
assert.throws(
149131
() => fs.write(i, common.mustNotCall()),
@@ -162,9 +144,12 @@ fs.open(fn4, 'w', 0o644, common.mustSucceed((fd) => {
162144
});
163145

164146
[
165-
false, 5, {}, [], null, undefined,
147+
false, 5, {}, [], null, undefined, true, 5n, () => {}, Symbol(), new Map(),
166148
new String('notPrimitive'),
167149
{ [Symbol.toPrimitive]: (hint) => 'amObject' },
150+
{ toString() { return 'amObject'; } },
151+
Promise.resolve('amPromise'),
152+
common.mustNotCall(),
168153
].forEach((data) => {
169154
assert.throws(
170155
() => fs.write(1, data, common.mustNotCall()),
@@ -184,7 +169,7 @@ fs.open(fn4, 'w', 0o644, common.mustSucceed((fd) => {
184169

185170
{
186171
// Regression test for https://github.com/nodejs/node/issues/38168
187-
const fd = fs.openSync(fn5, 'w');
172+
const fd = fs.openSync(fn4, 'w');
188173

189174
assert.throws(
190175
() => fs.writeSync(fd, 'abc', 0, 'hex'),

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.