Skip to content

Commit c4e7dca

Browse files
zbjornsontargos
authored andcommitted
fs: fix error when writing buffers > INT32_MAX
This reverts c380ee6. uv_fs_write returns an int, so it is not possible to ask it to write more than INT32_MAX. Instead, validate 'length' is an int32 in JS to avoid the assertion failure. PR-URL: #38546 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent 5df0f35 commit c4e7dca

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

lib/internal/fs/utils.js

+2
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ const validateOffsetLengthWrite = hideStackFrames(
624624
if (length < 0) {
625625
throw new ERR_OUT_OF_RANGE('length', '>= 0', length);
626626
}
627+
628+
validateInt32(length, 'length', 0);
627629
}
628630
);
629631

src/node_file.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1831,8 +1831,8 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
18311831
CHECK_LE(static_cast<uint64_t>(off_64), buffer_length);
18321832
const size_t off = static_cast<size_t>(off_64);
18331833

1834-
CHECK(IsSafeJsInt(args[3]));
1835-
const size_t len = static_cast<size_t>(args[3].As<Integer>()->Value());
1834+
CHECK(args[3]->IsInt32());
1835+
const size_t len = static_cast<size_t>(args[3].As<Int32>()->Value());
18361836
CHECK(Buffer::IsWithinBounds(off, len, buffer_length));
18371837
CHECK_LE(len, buffer_length);
18381838
CHECK_GE(off + len, off);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const path = require('path');
5+
const fs = require('fs');
6+
7+
const tmpdir = require('../common/tmpdir');
8+
tmpdir.refresh();
9+
10+
// fs.write with length > INT32_MAX
11+
12+
common.skipIf32Bits();
13+
14+
let buf;
15+
try {
16+
buf = Buffer.allocUnsafe(0x7FFFFFFF + 1);
17+
} catch (e) {
18+
// If the exception is not due to memory confinement then rethrow it.
19+
if (e.message !== 'Array buffer allocation failed') throw (e);
20+
common.skip('skipped due to memory requirements');
21+
}
22+
23+
const filename = path.join(tmpdir.path, 'write9.txt');
24+
fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => {
25+
assert.throws(() => {
26+
fs.write(fd,
27+
buf,
28+
0,
29+
0x7FFFFFFF + 1,
30+
0,
31+
common.mustNotCall());
32+
}, {
33+
code: 'ERR_OUT_OF_RANGE',
34+
name: 'RangeError',
35+
message: 'The value of "length" is out of range. ' +
36+
'It must be >= 0 && <= 2147483647. Received 2147483648'
37+
});
38+
39+
fs.closeSync(fd);
40+
}));

0 commit comments

Comments
 (0)