Skip to content

Commit 7ecf842

Browse files
bnoordhuiscodebytere
authored andcommitted
lib,src: switch Buffer::kMaxLength to size_t
Change the type of `Buffer::kMaxLength` to size_t because upcoming changes in V8 will allow typed arrays > 2 GB on 64 bits platforms. Not all platforms handle file reads and writes > 2 GB though so keep enforcing the 2 GB typed array limit for I/O operations. Fixes: #31399 Refs: libuv/libuv#1501 PR-URL: #31406 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Shelley Vohr <[email protected]>
1 parent 583d1d9 commit 7ecf842

File tree

6 files changed

+24
-14
lines changed

6 files changed

+24
-14
lines changed

lib/fs.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424

2525
'use strict';
2626

27+
// Most platforms don't allow reads or writes >= 2 GB.
28+
// See https://github.com/libuv/libuv/pull/1501.
29+
const kIoMaxLength = 2 ** 31 - 1;
30+
2731
const {
2832
Map,
2933
MathMax,
@@ -52,7 +56,7 @@ const {
5256
const pathModule = require('path');
5357
const { isArrayBufferView } = require('internal/util/types');
5458
const binding = internalBinding('fs');
55-
const { Buffer, kMaxLength } = require('buffer');
59+
const { Buffer } = require('buffer');
5660
const {
5761
codes: {
5862
ERR_FS_FILE_TOO_LARGE,
@@ -273,7 +277,7 @@ function readFileAfterStat(err, stats) {
273277

274278
const size = context.size = isFileType(stats, S_IFREG) ? stats[8] : 0;
275279

276-
if (size > kMaxLength) {
280+
if (size > kIoMaxLength) {
277281
err = new ERR_FS_FILE_TOO_LARGE(size);
278282
return context.close(err);
279283
}
@@ -330,7 +334,7 @@ function tryCreateBuffer(size, fd, isUserFd) {
330334
let threw = true;
331335
let buffer;
332336
try {
333-
if (size > kMaxLength) {
337+
if (size > kIoMaxLength) {
334338
throw new ERR_FS_FILE_TOO_LARGE(size);
335339
}
336340
buffer = Buffer.allocUnsafe(size);

lib/internal/errors.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -803,9 +803,7 @@ E('ERR_FALSY_VALUE_REJECTION', function(reason) {
803803
this.reason = reason;
804804
return 'Promise was rejected with falsy value';
805805
}, Error);
806-
E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than possible Buffer: ' +
807-
`${kMaxLength} bytes`,
808-
RangeError);
806+
E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than 2 GB', RangeError);
809807
E('ERR_FS_INVALID_SYMLINK_TYPE',
810808
'Symlink type must be one of "dir", "file", or "junction". Received "%s"',
811809
Error); // Switch to TypeError. The current implementation does not seem right

lib/internal/fs/promises.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
'use strict';
22

3+
// Most platforms don't allow reads or writes >= 2 GB.
4+
// See https://github.com/libuv/libuv/pull/1501.
5+
const kIoMaxLength = 2 ** 31 - 1;
6+
37
const {
48
MathMax,
59
MathMin,
@@ -15,7 +19,7 @@ const {
1519
S_IFREG
1620
} = internalBinding('constants').fs;
1721
const binding = internalBinding('fs');
18-
const { Buffer, kMaxLength } = require('buffer');
22+
const { Buffer } = require('buffer');
1923
const {
2024
ERR_FS_FILE_TOO_LARGE,
2125
ERR_INVALID_ARG_TYPE,
@@ -162,7 +166,7 @@ async function readFileHandle(filehandle, options) {
162166
size = 0;
163167
}
164168

165-
if (size > kMaxLength)
169+
if (size > kIoMaxLength)
166170
throw new ERR_FS_FILE_TOO_LARGE(size);
167171

168172
const chunks = [];

src/node_buffer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ using v8::Local;
6262
using v8::Maybe;
6363
using v8::MaybeLocal;
6464
using v8::Nothing;
65+
using v8::Number;
6566
using v8::Object;
6667
using v8::String;
6768
using v8::Uint32;
@@ -1156,7 +1157,7 @@ void Initialize(Local<Object> target,
11561157

11571158
target->Set(env->context(),
11581159
FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"),
1159-
Integer::NewFromUnsigned(env->isolate(), kMaxLength)).Check();
1160+
Number::New(env->isolate(), kMaxLength)).Check();
11601161

11611162
target->Set(env->context(),
11621163
FIXED_ONE_BYTE_STRING(env->isolate(), "kStringMaxLength"),

src/node_buffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace node {
2929

3030
namespace Buffer {
3131

32-
static const unsigned int kMaxLength = v8::TypedArray::kMaxLength;
32+
static const size_t kMaxLength = v8::TypedArray::kMaxLength;
3333

3434
typedef void (*FreeCallback)(char* data, void* hint);
3535

test/parallel/test-fs-util-validateoffsetlengthwrite.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ require('../common');
55

66
const assert = require('assert');
77
const { validateOffsetLengthWrite } = require('internal/fs/utils');
8-
const { kMaxLength } = require('buffer');
8+
9+
// Most platforms don't allow reads or writes >= 2 GB.
10+
// See https://github.com/libuv/libuv/pull/1501.
11+
const kIoMaxLength = 2 ** 31 - 1;
912

1013
// RangeError when offset > byteLength
1114
{
@@ -23,11 +26,11 @@ const { kMaxLength } = require('buffer');
2326
);
2427
}
2528

26-
// RangeError when byteLength < kMaxLength, and length > byteLength - offset .
29+
// RangeError when byteLength < kIoMaxLength, and length > byteLength - offset.
2730
{
28-
const offset = kMaxLength - 150;
31+
const offset = kIoMaxLength - 150;
2932
const length = 200;
30-
const byteLength = kMaxLength - 100;
33+
const byteLength = kIoMaxLength - 100;
3134
assert.throws(
3235
() => validateOffsetLengthWrite(offset, length, byteLength),
3336
{

0 commit comments

Comments
 (0)