Skip to content

Commit 6bbe285

Browse files
targosjasnell
authored andcommitted
fs: use byteLength to handle ArrayBuffer views
Unlike TypedArray, DataView doesn't have a length property. PR-URL: #38187 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Darshan Sen <[email protected]>
1 parent 474fbb5 commit 6bbe285

File tree

4 files changed

+57
-34
lines changed

4 files changed

+57
-34
lines changed

Diff for: doc/api/fs.md

+27-21
Original file line numberDiff line numberDiff line change
@@ -265,18 +265,20 @@ added: v10.0.0
265265
added: v10.0.0
266266
-->
267267
268-
* `buffer` {Buffer|Uint8Array} A buffer that will be filled with the file
269-
data read.
268+
* `buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the
269+
file data read.
270270
* `offset` {integer} The location in the buffer at which to start filling.
271271
**Default:** `0`
272-
* `length` {integer} The number of bytes to read. **Default:** `buffer.length`
272+
* `length` {integer} The number of bytes to read. **Default:**
273+
`buffer.byteLength`
273274
* `position` {integer} The location where to begin reading data from the
274275
file. If `null`, data will be read from the current file position, and
275276
the position will be updated. If `position` is an integer, the current
276277
file position will remain unchanged.
277278
* Returns: {Promise} Fulfills upon success with an object with two properties:
278279
* `bytesRead` {integer} The number of bytes read
279-
* `buffer` {Buffer|Uint8Array} A reference to the passed in `buffer` argument.
280+
* `buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer`
281+
argument.
280282
281283
Reads data from the file and stores that in the given buffer.
282284
@@ -290,19 +292,20 @@ added:
290292
- v12.17.0
291293
-->
292294
* `options` {Object}
293-
* `buffer` {Buffer|Uint8Array} A buffer that will be filled with the file
294-
data read. **Default:** `Buffer.alloc(16384)`
295+
* `buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the
296+
file data read. **Default:** `Buffer.alloc(16384)`
295297
* `offset` {integer} The location in the buffer at which to start filling.
296298
**Default:** `0`
297-
* `length` {integer} The number of bytes to read. **Default:** `buffer.length`
299+
* `length` {integer} The number of bytes to read. **Default:**
300+
`buffer.byteLength`
298301
* `position` {integer} The location where to begin reading data from the
299302
file. If `null`, data will be read from the current file position, and
300303
the position will be updated. If `position` is an integer, the current
301304
file position will remain unchanged. **Default:**: `null`
302305
* Returns: {Promise} Fulfills upon success with an object with two properties:
303306
* `bytesRead` {integer} The number of bytes read
304-
* `buffer` {Buffer|Uint8Array} A reference to the passed in `buffer`
305-
argument.
307+
* `buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer`
308+
argument.
306309
307310
Reads data from the file and stores that in the given buffer.
308311
@@ -434,10 +437,11 @@ changes:
434437
buffers anymore.
435438
-->
436439
437-
* `buffer` {Buffer|Uint8Array|string|Object}
440+
* `buffer` {Buffer|TypedArray|DataView|string|Object}
438441
* `offset` {integer} The start position from within `buffer` where the data
439-
to write begins.
440-
* `length` {integer} The number of bytes from `buffer` to write.
442+
to write begins. **Default:** `0`
443+
* `length` {integer} The number of bytes from `buffer` to write. **Default:**
444+
`buffer.byteLength`
441445
* `position` {integer} The offset from the beginning of the file where the
442446
data from `buffer` should be written. If `position` is not a `number`,
443447
the data will be written at the current position. See the POSIX pwrite(2)
@@ -449,8 +453,8 @@ Write `buffer` to the file.
449453
The promise is resolved with an object containing two properties:
450454
451455
* `bytesWritten` {integer} the number of bytes written
452-
* `buffer` {Buffer|Uint8Array|string|Object} a reference to the `buffer`
453-
written.
456+
* `buffer` {Buffer|TypedArray|DataView|string|Object} a reference to the
457+
`buffer` written.
454458
455459
It is unsafe to use `filehandle.write()` multiple times on the same file
456460
without waiting for the promise to be resolved (or rejected). For this
@@ -512,7 +516,7 @@ changes:
512516
strings anymore.
513517
-->
514518
515-
* `data` {string|Buffer|Uint8Array|Object}
519+
* `data` {string|Buffer|TypedArray|DataView|Object}
516520
* `options` {Object|string}
517521
* `encoding` {string|null} The expected character encoding when `data` is a
518522
string. **Default:** `'utf8'`
@@ -1270,7 +1274,7 @@ changes:
12701274
-->
12711275
12721276
* `file` {string|Buffer|URL|FileHandle} filename or `FileHandle`
1273-
* `data` {string|Buffer|Uint8Array|Object|AsyncIterable|Iterable
1277+
* `data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable
12741278
|Stream}
12751279
* `options` {Object|string}
12761280
* `encoding` {string|null} **Default:** `'utf8'`
@@ -2722,9 +2726,11 @@ changes:
27222726
27232727
* `fd` {integer}
27242728
* `buffer` {Buffer|TypedArray|DataView} The buffer that the data will be
2725-
written to.
2726-
* `offset` {integer} The position in `buffer` to write the data to.
2727-
* `length` {integer} The number of bytes to read.
2729+
written to. **Default:** `Buffer.alloc(16384)`
2730+
* `offset` {integer} The position in `buffer` to write the data to. **Default:**
2731+
`0`
2732+
* `length` {integer} The number of bytes to read. **Default:**
2733+
`buffer.byteLength`
27282734
* `position` {integer|bigint} Specifies where to begin reading from in the
27292735
file. If `position` is `null` or `-1 `, data will be read from the current
27302736
file position, and the file position will be updated. If `position` is an
@@ -2761,7 +2767,7 @@ changes:
27612767
* `options` {Object}
27622768
* `buffer` {Buffer|TypedArray|DataView} **Default:** `Buffer.alloc(16384)`
27632769
* `offset` {integer} **Default:** `0`
2764-
* `length` {integer} **Default:** `buffer.length`
2770+
* `length` {integer} **Default:** `buffer.byteLength`
27652771
* `position` {integer|bigint} **Default:** `null`
27662772
* `callback` {Function}
27672773
* `err` {Error}
@@ -4689,7 +4695,7 @@ changes:
46894695
* `buffer` {Buffer|TypedArray|DataView}
46904696
* `options` {Object}
46914697
* `offset` {integer} **Default:** `0`
4692-
* `length` {integer} **Default:** `buffer.length`
4698+
* `length` {integer} **Default:** `buffer.byteLength`
46934699
* `position` {integer|bigint} **Default:** `null`
46944700
* Returns: {number}
46954701

Diff for: lib/fs.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ function read(fd, buffer, offset, length, position, callback) {
532532
({
533533
buffer = Buffer.alloc(16384),
534534
offset = 0,
535-
length = buffer.length,
535+
length = buffer.byteLength,
536536
position
537537
} = options);
538538
}
@@ -587,15 +587,15 @@ ObjectDefineProperty(read, internalUtil.customPromisifyArgs,
587587
function readSync(fd, buffer, offset, length, position) {
588588
fd = getValidatedFd(fd);
589589

590+
validateBuffer(buffer);
591+
590592
if (arguments.length <= 3) {
591593
// Assume fs.read(fd, buffer, options)
592594
const options = offset || {};
593595

594-
({ offset = 0, length = buffer.length, position } = options);
596+
({ offset = 0, length = buffer.byteLength, position } = options);
595597
}
596598

597-
validateBuffer(buffer);
598-
599599
if (offset == null) {
600600
offset = 0;
601601
} else {
@@ -682,7 +682,7 @@ function write(fd, buffer, offset, length, position, callback) {
682682
validateInteger(offset, 'offset');
683683
}
684684
if (typeof length !== 'number')
685-
length = buffer.length - offset;
685+
length = buffer.byteLength - offset;
686686
if (typeof position !== 'number')
687687
position = null;
688688
validateOffsetLengthWrite(offset, length, buffer.byteLength);

Diff for: lib/internal/fs/promises.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -280,19 +280,19 @@ async function writeFileHandle(filehandle, data, signal, encoding) {
280280
checkAborted(signal);
281281
await write(
282282
filehandle, buf, undefined,
283-
isArrayBufferView(buf) ? buf.length : encoding);
283+
isArrayBufferView(buf) ? buf.byteLength : encoding);
284284
checkAborted(signal);
285285
}
286286
return;
287287
}
288288
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
289-
let remaining = data.length;
289+
let remaining = data.byteLength;
290290
if (remaining === 0) return;
291291
do {
292292
checkAborted(signal);
293293
const { bytesWritten } =
294294
await write(filehandle, data, 0,
295-
MathMin(kWriteFileMaxChunkSize, data.length));
295+
MathMin(kWriteFileMaxChunkSize, data.byteLength));
296296
remaining -= bytesWritten;
297297
data = new Uint8Array(
298298
data.buffer,
@@ -404,7 +404,7 @@ async function read(handle, bufferOrOptions, offset, length, position) {
404404
buffer = Buffer.alloc(16384);
405405
}
406406
offset = bufferOrOptions.offset || 0;
407-
length = buffer.length;
407+
length = buffer.byteLength;
408408
position = bufferOrOptions.position || null;
409409
}
410410

@@ -419,12 +419,12 @@ async function read(handle, bufferOrOptions, offset, length, position) {
419419
if (length === 0)
420420
return { bytesRead: length, buffer };
421421

422-
if (buffer.length === 0) {
422+
if (buffer.byteLength === 0) {
423423
throw new ERR_INVALID_ARG_VALUE('buffer', buffer,
424424
'is empty and cannot be written');
425425
}
426426

427-
validateOffsetLengthRead(offset, length, buffer.length);
427+
validateOffsetLengthRead(offset, length, buffer.byteLength);
428428

429429
if (!NumberIsSafeInteger(position))
430430
position = -1;
@@ -447,7 +447,7 @@ async function readv(handle, buffers, position) {
447447
}
448448

449449
async function write(handle, buffer, offset, length, position) {
450-
if (buffer?.length === 0)
450+
if (buffer?.byteLength === 0)
451451
return { bytesWritten: 0, buffer };
452452

453453
if (isArrayBufferView(buffer)) {
@@ -457,7 +457,7 @@ async function write(handle, buffer, offset, length, position) {
457457
validateInteger(offset, 'offset');
458458
}
459459
if (typeof length !== 'number')
460-
length = buffer.length - offset;
460+
length = buffer.byteLength - offset;
461461
if (typeof position !== 'number')
462462
position = null;
463463
validateOffsetLengthWrite(offset, length, buffer.byteLength);

Diff for: test/parallel/test-fs-write-buffer.js

+17
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,20 @@ tmpdir.refresh();
146146
fs.closeSync(fd);
147147
}));
148148
}
149+
150+
// fs.write with a DataView, without the offset and length parameters:
151+
{
152+
const filename = path.join(tmpdir.path, 'write8.txt');
153+
fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => {
154+
const cb = common.mustSucceed((written) => {
155+
assert.strictEqual(written, expected.length);
156+
fs.closeSync(fd);
157+
158+
const found = fs.readFileSync(filename, 'utf8');
159+
assert.strictEqual(found, expected.toString());
160+
});
161+
162+
const uint8 = Uint8Array.from(expected);
163+
fs.write(fd, new DataView(uint8.buffer), cb);
164+
}));
165+
}

0 commit comments

Comments
 (0)