Skip to content

Commit e876118

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 3bb12db commit e876118

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

lib/internal/fs/utils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ const validateOffsetLengthWrite = hideStackFrames(
659659
if (length < 0) {
660660
throw new ERR_OUT_OF_RANGE('length', '>= 0', length);
661661
}
662+
663+
validateInt32(length, 'length', 0);
662664
}
663665
);
664666

src/node_file.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,8 +1835,8 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
18351835
CHECK_LE(static_cast<uint64_t>(off_64), buffer_length);
18361836
const size_t off = static_cast<size_t>(off_64);
18371837

1838-
CHECK(IsSafeJsInt(args[3]));
1839-
const size_t len = static_cast<size_t>(args[3].As<Integer>()->Value());
1838+
CHECK(args[3]->IsInt32());
1839+
const size_t len = static_cast<size_t>(args[3].As<Int32>()->Value());
18401840
CHECK(Buffer::IsWithinBounds(off, len, buffer_length));
18411841
CHECK_LE(len, buffer_length);
18421842
CHECK_GE(off + len, off);
Lines changed: 40 additions & 0 deletions
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)