fs: allow int64 offset in fs.write/writeSync/fd.write
Ref https://github.com/nodejs/node/issues/26563 PR-URL: https://github.com/nodejs/node/pull/26572 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
parent
a3c0014e73
commit
5e3b4d6ed9
10
lib/fs.js
10
lib/fs.js
@ -541,8 +541,11 @@ function write(fd, buffer, offset, length, position, callback) {
|
|||||||
|
|
||||||
if (isArrayBufferView(buffer)) {
|
if (isArrayBufferView(buffer)) {
|
||||||
callback = maybeCallback(callback || position || length || offset);
|
callback = maybeCallback(callback || position || length || offset);
|
||||||
if (typeof offset !== 'number')
|
if (offset == null || typeof offset === 'function') {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
validateSafeInteger(offset, 'offset');
|
||||||
|
}
|
||||||
if (typeof length !== 'number')
|
if (typeof length !== 'number')
|
||||||
length = buffer.length - offset;
|
length = buffer.length - offset;
|
||||||
if (typeof position !== 'number')
|
if (typeof position !== 'number')
|
||||||
@ -580,8 +583,11 @@ function writeSync(fd, buffer, offset, length, position) {
|
|||||||
if (isArrayBufferView(buffer)) {
|
if (isArrayBufferView(buffer)) {
|
||||||
if (position === undefined)
|
if (position === undefined)
|
||||||
position = null;
|
position = null;
|
||||||
if (typeof offset !== 'number')
|
if (offset == null) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
validateSafeInteger(offset, 'offset');
|
||||||
|
}
|
||||||
if (typeof length !== 'number')
|
if (typeof length !== 'number')
|
||||||
length = buffer.byteLength - offset;
|
length = buffer.byteLength - offset;
|
||||||
validateOffsetLengthWrite(offset, length, buffer.byteLength);
|
validateOffsetLengthWrite(offset, length, buffer.byteLength);
|
||||||
|
@ -240,8 +240,11 @@ async function write(handle, buffer, offset, length, position) {
|
|||||||
return { bytesWritten: 0, buffer };
|
return { bytesWritten: 0, buffer };
|
||||||
|
|
||||||
if (isUint8Array(buffer)) {
|
if (isUint8Array(buffer)) {
|
||||||
if (typeof offset !== 'number')
|
if (offset == null) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
validateSafeInteger(offset, 'offset');
|
||||||
|
}
|
||||||
if (typeof length !== 'number')
|
if (typeof length !== 'number')
|
||||||
length = buffer.length - offset;
|
length = buffer.length - offset;
|
||||||
if (typeof position !== 'number')
|
if (typeof position !== 'number')
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
const { Object, Reflect } = primordials;
|
const { Object, Reflect } = primordials;
|
||||||
|
|
||||||
const { Buffer, kMaxLength } = require('buffer');
|
const { Buffer } = require('buffer');
|
||||||
const {
|
const {
|
||||||
codes: {
|
codes: {
|
||||||
ERR_FS_INVALID_SYMLINK_TYPE,
|
ERR_FS_INVALID_SYMLINK_TYPE,
|
||||||
@ -476,9 +476,8 @@ const validateOffsetLengthWrite = hideStackFrames(
|
|||||||
throw new ERR_OUT_OF_RANGE('offset', `<= ${byteLength}`, offset);
|
throw new ERR_OUT_OF_RANGE('offset', `<= ${byteLength}`, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const max = byteLength > kMaxLength ? kMaxLength : byteLength;
|
if (length > byteLength - offset) {
|
||||||
if (length > max - offset) {
|
throw new ERR_OUT_OF_RANGE('length', `<= ${byteLength - offset}`, length);
|
||||||
throw new ERR_OUT_OF_RANGE('length', `<= ${max - offset}`, length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -88,7 +88,7 @@ constexpr char kPathSeparator = '/';
|
|||||||
const char* const kPathSeparator = "\\/";
|
const char* const kPathSeparator = "\\/";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GET_OFFSET(a) ((a)->IsNumber() ? (a).As<Integer>()->Value() : -1)
|
#define GET_OFFSET(a) (IsSafeJsInt(a) ? (a).As<Integer>()->Value() : -1)
|
||||||
#define TRACE_NAME(name) "fs.sync." #name
|
#define TRACE_NAME(name) "fs.sync." #name
|
||||||
#define GET_TRACE_ENABLED \
|
#define GET_TRACE_ENABLED \
|
||||||
(*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
|
(*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
|
||||||
@ -1669,9 +1669,11 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
|
|||||||
char* buffer_data = Buffer::Data(buffer_obj);
|
char* buffer_data = Buffer::Data(buffer_obj);
|
||||||
size_t buffer_length = Buffer::Length(buffer_obj);
|
size_t buffer_length = Buffer::Length(buffer_obj);
|
||||||
|
|
||||||
CHECK(args[2]->IsInt32());
|
CHECK(IsSafeJsInt(args[2]));
|
||||||
const size_t off = static_cast<size_t>(args[2].As<Int32>()->Value());
|
const int64_t off_64 = args[2].As<Integer>()->Value();
|
||||||
CHECK_LE(off, buffer_length);
|
CHECK_GE(off_64, 0);
|
||||||
|
CHECK_LE(static_cast<uint64_t>(off_64), buffer_length);
|
||||||
|
const size_t off = static_cast<size_t>(off_64);
|
||||||
|
|
||||||
CHECK(args[3]->IsInt32());
|
CHECK(args[3]->IsInt32());
|
||||||
const size_t len = static_cast<size_t>(args[3].As<Int32>()->Value());
|
const size_t len = static_cast<size_t>(args[3].As<Int32>()->Value());
|
||||||
|
@ -22,22 +22,6 @@ const { kMaxLength } = require('buffer');
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RangeError when byteLength > kMaxLength, and length > kMaxLength - offset .
|
|
||||||
{
|
|
||||||
const offset = kMaxLength;
|
|
||||||
const length = 100;
|
|
||||||
const byteLength = kMaxLength + 1;
|
|
||||||
common.expectsError(
|
|
||||||
() => validateOffsetLengthWrite(offset, length, byteLength),
|
|
||||||
{
|
|
||||||
code: 'ERR_OUT_OF_RANGE',
|
|
||||||
type: RangeError,
|
|
||||||
message: 'The value of "length" is out of range. ' +
|
|
||||||
`It must be <= ${kMaxLength - offset}. Received ${length}`
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// RangeError when byteLength < kMaxLength, and length > byteLength - offset .
|
// RangeError when byteLength < kMaxLength, and length > byteLength - offset .
|
||||||
{
|
{
|
||||||
const offset = kMaxLength - 150;
|
const offset = kMaxLength - 150;
|
||||||
|
@ -148,3 +148,27 @@ tmpdir.refresh();
|
|||||||
fs.write(fd, Uint8Array.from(expected), cb);
|
fs.write(fd, Uint8Array.from(expected), cb);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.write with invalid offset type
|
||||||
|
{
|
||||||
|
const filename = path.join(tmpdir.path, 'write7.txt');
|
||||||
|
fs.open(filename, 'w', 0o644, common.mustCall((err, fd) => {
|
||||||
|
assert.ifError(err);
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
fs.write(fd,
|
||||||
|
Buffer.from('abcd'),
|
||||||
|
NaN,
|
||||||
|
expected.length,
|
||||||
|
0,
|
||||||
|
common.mustNotCall());
|
||||||
|
}, {
|
||||||
|
code: 'ERR_OUT_OF_RANGE',
|
||||||
|
name: 'RangeError',
|
||||||
|
message: 'The value of "offset" is out of range. ' +
|
||||||
|
'It must be an integer. Received NaN'
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user