Skip to content

Commit cb8c81c

Browse files
LiviaMedeirosxtx1130
authored andcommittedApr 25, 2022
fs: adjust default length for fs.readSync and fsPromises/read
Makes default length reasonable when nonzero offset is set. PR-URL: nodejs#42128 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent b70bc40 commit cb8c81c

File tree

4 files changed

+62
-30
lines changed

4 files changed

+62
-30
lines changed
 

‎doc/api/fs.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5396,7 +5396,7 @@ changes:
53965396
* `buffer` {Buffer|TypedArray|DataView}
53975397
* `options` {Object}
53985398
* `offset` {integer} **Default:** `0`
5399-
* `length` {integer} **Default:** `buffer.byteLength`
5399+
* `length` {integer} **Default:** `buffer.byteLength - offset`
54005400
* `position` {integer|bigint} **Default:** `null`
54015401
* Returns: {number}
54025402

‎lib/fs.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ function read(fd, buffer, offset, length, position, callback) {
604604

605605
if (arguments.length <= 3) {
606606
// Assume fs.read(fd, options, callback)
607-
let options = {};
607+
let options = ObjectCreate(null);
608608
if (arguments.length < 3) {
609609
// This is fs.read(fd, callback)
610610
// buffer will be the callback
@@ -621,7 +621,7 @@ function read(fd, buffer, offset, length, position, callback) {
621621
buffer = Buffer.alloc(16384),
622622
offset = 0,
623623
length = buffer.byteLength - offset,
624-
position
624+
position = null
625625
} = options);
626626
}
627627

@@ -686,10 +686,14 @@ function readSync(fd, buffer, offset, length, position) {
686686
validateBuffer(buffer);
687687

688688
if (arguments.length <= 3) {
689-
// Assume fs.read(fd, buffer, options)
690-
const options = offset || {};
689+
// Assume fs.readSync(fd, buffer, options)
690+
const options = offset || ObjectCreate(null);
691691

692-
({ offset = 0, length = buffer.byteLength, position } = options);
692+
({
693+
offset = 0,
694+
length = buffer.byteLength - offset,
695+
position = null
696+
} = options);
693697
}
694698

695699
if (offset == null) {

‎lib/internal/fs/promises.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
Error,
66
MathMax,
77
MathMin,
8+
ObjectCreate,
89
NumberIsSafeInteger,
910
Promise,
1011
PromisePrototypeThen,
@@ -510,18 +511,15 @@ async function open(path, flags, mode) {
510511
async function read(handle, bufferOrOptions, offset, length, position) {
511512
let buffer = bufferOrOptions;
512513
if (!isArrayBufferView(buffer)) {
513-
if (bufferOrOptions === undefined) {
514-
bufferOrOptions = {};
515-
}
516-
if (bufferOrOptions.buffer) {
517-
buffer = bufferOrOptions.buffer;
518-
validateBuffer(buffer);
519-
} else {
520-
buffer = Buffer.alloc(16384);
521-
}
522-
offset = bufferOrOptions.offset || 0;
523-
length = bufferOrOptions.length ?? buffer.byteLength;
524-
position = bufferOrOptions.position ?? null;
514+
bufferOrOptions ??= ObjectCreate(null);
515+
({
516+
buffer = Buffer.alloc(16384),
517+
offset = 0,
518+
length = buffer.byteLength - offset,
519+
position = null
520+
} = bufferOrOptions);
521+
522+
validateBuffer(buffer);
525523
}
526524

527525
if (offset == null) {

‎test/parallel/test-fs-readSync-optional-params.js

+42-12
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,53 @@ const fixtures = require('../common/fixtures');
55
const fs = require('fs');
66
const assert = require('assert');
77
const filepath = fixtures.path('x.txt');
8-
const fd = fs.openSync(filepath, 'r');
98

109
const expected = Buffer.from('xyz\n');
1110

1211
function runTest(defaultBuffer, options) {
13-
const result = fs.readSync(fd, defaultBuffer, options);
14-
assert.strictEqual(result, expected.length);
15-
assert.deepStrictEqual(defaultBuffer, expected);
12+
let fd;
13+
try {
14+
fd = fs.openSync(filepath, 'r');
15+
const result = fs.readSync(fd, defaultBuffer, options);
16+
assert.strictEqual(result, expected.length);
17+
assert.deepStrictEqual(defaultBuffer, expected);
18+
} finally {
19+
if (fd != null) fs.closeSync(fd);
20+
}
1621
}
1722

18-
// Test passing in an empty options object
19-
runTest(Buffer.allocUnsafe(expected.length), { position: 0 });
23+
for (const options of [
2024

21-
// Test not passing in any options object
22-
runTest(Buffer.allocUnsafe(expected.length));
25+
// Test options object
26+
{ offset: 0 },
27+
{ length: expected.length },
28+
{ position: 0 },
29+
{ offset: 0, length: expected.length },
30+
{ offset: 0, position: 0 },
31+
{ length: expected.length, position: 0 },
32+
{ offset: 0, length: expected.length, position: 0 },
2333

24-
// Test passing in options
25-
runTest(Buffer.allocUnsafe(expected.length), { offset: 0,
26-
length: expected.length,
27-
position: 0 });
34+
{ offset: null },
35+
{ position: null },
36+
{ position: -1 },
37+
{ position: 0n },
38+
39+
// Test default params
40+
{},
41+
null,
42+
undefined,
43+
44+
// Test if bad params are interpreted as default (not mandatory)
45+
false,
46+
true,
47+
Infinity,
48+
42n,
49+
Symbol(),
50+
51+
// Test even more malicious corner cases
52+
'4'.repeat(expected.length),
53+
new String('4444'),
54+
[4, 4, 4, 4],
55+
]) {
56+
runTest(Buffer.allocUnsafe(expected.length), options);
57+
}

0 commit comments

Comments
 (0)