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

3 files changed

Lines changed: 44 additions & 2 deletions

File tree

‎lib/internal/fs/utils.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ const validateOffsetLengthWrite = hideStackFrames(
624624
if(length<0){
625625
thrownewERR_OUT_OF_RANGE('length','>= 0',length);
626626
}
627+
628+
validateInt32(length,'length',0);
627629
}
628630
);
629631

‎src/node_file.cc‎

Lines changed: 2 additions & 2 deletions
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
constsize_t off = static_cast<size_t>(off_64);
18331833

1834-
CHECK(IsSafeJsInt(args[3]));
1835-
constsize_t len = static_cast<size_t>(args[3].As<Integer>()->Value());
1834+
CHECK(args[3]->IsInt32());
1835+
constsize_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);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constassert=require('assert');
4+
constpath=require('path');
5+
constfs=require('fs');
6+
7+
consttmpdir=require('../common/tmpdir');
8+
tmpdir.refresh();
9+
10+
// fs.write with length > INT32_MAX
11+
12+
common.skipIf32Bits();
13+
14+
letbuf;
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+
constfilename=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)