Skip to content

Commit 2dc549a

Browse files
committed
buffer: cleanup handling different types buffers
PR-URL: #54439 Assisted-by: Claude Code:Opus 4.6
1 parent f1ed8d6 commit 2dc549a

File tree

1 file changed

+69
-55
lines changed

1 file changed

+69
-55
lines changed

lib/buffer.js

Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,7 @@ const {
4545
SymbolSpecies,
4646
SymbolToPrimitive,
4747
TypedArrayPrototypeFill,
48-
TypedArrayPrototypeGetBuffer,
49-
TypedArrayPrototypeGetByteLength,
50-
TypedArrayPrototypeGetByteOffset,
51-
TypedArrayPrototypeGetLength,
5248
TypedArrayPrototypeSet,
53-
TypedArrayPrototypeSubarray,
5449
Uint8Array,
5550
} = primordials;
5651

@@ -104,7 +99,6 @@ const {
10499
isAnyArrayBuffer,
105100
isArrayBufferView,
106101
isUint8Array,
107-
isTypedArray,
108102
} = require('internal/util/types');
109103
const {
110104
inspect: utilInspect,
@@ -154,6 +148,15 @@ FastBuffer.prototype.constructor = Buffer;
154148
Buffer.prototype = FastBuffer.prototype;
155149
addBufferPrototypeMethods(Buffer.prototype);
156150

151+
const BUFFER_NAMES = [
152+
'ArrayBuffer',
153+
'Buffer',
154+
'TypedArray',
155+
'DataView',
156+
'ArrayBuffer',
157+
'SharedArrayBuffer',
158+
];
159+
157160
const constants = ObjectDefineProperties({}, {
158161
MAX_LENGTH: {
159162
__proto__: null,
@@ -232,10 +235,13 @@ function toInteger(n, defaultVal) {
232235
}
233236

234237
function copyImpl(source, target, targetStart, sourceStart, sourceEnd) {
235-
if (!ArrayBufferIsView(source))
236-
throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source);
237-
if (!ArrayBufferIsView(target))
238-
throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target);
238+
if (isArrayBufferView(target)) {
239+
// Do nothing..
240+
} else if (isAnyArrayBuffer(target)) {
241+
target = new Uint8Array(target);
242+
} else {
243+
throw new ERR_INVALID_ARG_TYPE('target', BUFFER_NAMES, target);
244+
}
239245

240246
if (targetStart === undefined) {
241247
targetStart = 0;
@@ -359,25 +365,29 @@ Buffer.from = function from(value, encodingOrOffset, length) {
359365

360366
throw new ERR_INVALID_ARG_TYPE(
361367
'first argument',
362-
['string', 'Buffer', 'ArrayBuffer', 'Array', 'Array-like Object'],
368+
['string', 'Array', 'Array-like Object', ...BUFFER_NAMES],
363369
value,
364370
);
365371
};
366372

367373
/**
368374
* Creates the Buffer as a copy of the underlying ArrayBuffer of the view
369375
* rather than the contents of the view.
370-
* @param {TypedArray} view
376+
* @param {Buffer|TypedArray|DataView} view
371377
* @param {number} [offset]
372378
* @param {number} [length]
373379
* @returns {Buffer}
374380
*/
375381
Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
376-
if (!isTypedArray(view)) {
377-
throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view);
382+
if (isArrayBufferView(view)) {
383+
// Do nothing..
384+
} else if (isAnyArrayBuffer(view)) {
385+
view = new Uint8Array(view);
386+
} else {
387+
throw new ERR_INVALID_ARG_TYPE('view', BUFFER_NAMES, view);
378388
}
379389

380-
const viewLength = TypedArrayPrototypeGetLength(view);
390+
const viewLength = view.byteLength;
381391
if (viewLength === 0) {
382392
return new FastBuffer();
383393
}
@@ -399,16 +409,16 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
399409

400410
if (end <= start) return new FastBuffer();
401411

402-
const viewByteLength = TypedArrayPrototypeGetByteLength(view);
412+
const viewByteLength = view.byteLength;
403413
const elementSize = viewByteLength / viewLength;
404-
const srcByteOffset = TypedArrayPrototypeGetByteOffset(view) +
414+
const srcByteOffset = view.byteOffset +
405415
start * elementSize;
406416
const srcByteLength = (end - start) * elementSize;
407417

408418
return fromArrayLike(new Uint8Array(
409-
TypedArrayPrototypeGetBuffer(view),
419+
view.buffer,
410420
srcByteOffset,
411-
srcByteLength));
421+
srcByteLength))
412422
};
413423

414424
// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
@@ -621,20 +631,20 @@ Buffer.concat = function concat(list, length) {
621631
length = 0;
622632
for (let i = 0; i < list.length; i++) {
623633
const buf = list[i];
624-
if (!isUint8Array(buf)) {
634+
if (!isArrayBufferView(buf) && !isAnyArrayBuffer(buf)) {
625635
// TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
626636
// Instead, find the proper error code for this.
627637
throw new ERR_INVALID_ARG_TYPE(
628-
`list[${i}]`, ['Buffer', 'Uint8Array'], buf);
638+
`list[${i}]`, BUFFER_NAMES, buf);
629639
}
630-
length += TypedArrayPrototypeGetByteLength(buf);
640+
length += buf.byteLength;
631641
}
632642

633643
const buffer = allocate(length);
634644
let pos = 0;
635645
for (let i = 0; i < list.length; i++) {
636646
const buf = list[i];
637-
const bufLength = TypedArrayPrototypeGetByteLength(buf);
647+
const bufLength = buf.byteLength;
638648
TypedArrayPrototypeSet(buffer, buf, pos);
639649
pos += bufLength;
640650
}
@@ -647,22 +657,22 @@ Buffer.concat = function concat(list, length) {
647657

648658
validateOffset(length, 'length');
649659
for (let i = 0; i < list.length; i++) {
650-
if (!isUint8Array(list[i])) {
660+
if (!isArrayBufferView(list[i]) && !isAnyArrayBuffer(list[i])) {
651661
// TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
652662
// Instead, find the proper error code for this.
653663
throw new ERR_INVALID_ARG_TYPE(
654-
`list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);
664+
`list[${i}]`, BUFFER_NAMES, list[i]);
655665
}
656666
}
657667

658668
const buffer = allocate(length);
659669
let pos = 0;
660670
for (let i = 0; i < list.length; i++) {
661671
const buf = list[i];
662-
const bufLength = TypedArrayPrototypeGetByteLength(buf);
672+
const bufLength = buf.byteLength;
663673
if (pos + bufLength > length) {
664674
TypedArrayPrototypeSet(buffer,
665-
TypedArrayPrototypeSubarray(buf, 0, length - pos),
675+
buf.subarray(0, length - pos),
666676
pos);
667677
pos = length;
668678
break;
@@ -834,10 +844,7 @@ function byteLength(string, encoding) {
834844
if (isArrayBufferView(string) || isAnyArrayBuffer(string)) {
835845
return string.byteLength;
836846
}
837-
838-
throw new ERR_INVALID_ARG_TYPE(
839-
'string', ['string', 'Buffer', 'ArrayBuffer'], string,
840-
);
847+
throw new ERR_INVALID_ARG_TYPE('string', ['string', ...BUFFER_NAMES], string);
841848
}
842849

843850
const len = string.length;
@@ -898,7 +905,7 @@ Buffer.prototype.toString = function toString(encoding, start, end) {
898905
return utf8Slice(this, 0, this.length);
899906
}
900907

901-
const bufferLength = TypedArrayPrototypeGetLength(this);
908+
const bufferLength = this.length;
902909

903910
if (start <= 0)
904911
start = 0;
@@ -926,15 +933,18 @@ Buffer.prototype.toString = function toString(encoding, start, end) {
926933
};
927934

928935
Buffer.prototype.equals = function equals(otherBuffer) {
929-
if (!isUint8Array(otherBuffer)) {
930-
throw new ERR_INVALID_ARG_TYPE(
931-
'otherBuffer', ['Buffer', 'Uint8Array'], otherBuffer);
936+
if (isArrayBufferView(otherBuffer)) {
937+
// Do nothing..
938+
} else if (isAnyArrayBuffer(otherBuffer)) {
939+
otherBuffer = new Uint8Array(otherBuffer);
940+
} else {
941+
throw new ERR_INVALID_ARG_TYPE('otherBuffer', BUFFER_NAMES, otherBuffer);
932942
}
933943

934944
if (this === otherBuffer)
935945
return true;
936-
const len = TypedArrayPrototypeGetByteLength(this);
937-
if (len !== TypedArrayPrototypeGetByteLength(otherBuffer))
946+
const len = this.byteLength;
947+
if (len !== otherBuffer.byteLength)
938948
return false;
939949

940950
return len === 0 || _compare(this, otherBuffer) === 0;
@@ -988,9 +998,14 @@ Buffer.prototype.compare = function compare(target,
988998
targetEnd,
989999
sourceStart,
9901000
sourceEnd) {
991-
if (!isUint8Array(target)) {
992-
throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target);
1001+
if (isArrayBufferView(target)) {
1002+
// Do nothing..
1003+
} else if (isAnyArrayBuffer(target)) {
1004+
target = new Uint8Array(target);
1005+
} else {
1006+
throw new ERR_INVALID_ARG_TYPE('target', BUFFER_NAMES, target);
9931007
}
1008+
9941009
if (arguments.length === 1)
9951010
return _compare(this, target);
9961011

@@ -1066,14 +1081,14 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
10661081
return ops.indexOf(buffer, val, byteOffset, dir);
10671082
}
10681083

1069-
if (isUint8Array(val)) {
1084+
if (isArrayBufferView(val) || isAnyArrayBuffer(val)) {
10701085
const encodingVal =
10711086
(ops === undefined ? encodingsMap.utf8 : ops.encodingVal);
10721087
return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir);
10731088
}
10741089

10751090
throw new ERR_INVALID_ARG_TYPE(
1076-
'value', ['number', 'string', 'Buffer', 'Uint8Array'], val,
1091+
'value', ['number', 'string', ...BUFFER_NAMES], val,
10771092
);
10781093
}
10791094

@@ -1152,7 +1167,7 @@ function _fill(buf, value, offset, end, encoding) {
11521167

11531168
if (typeof value === 'number') {
11541169
// OOB check
1155-
const byteLen = TypedArrayPrototypeGetByteLength(buf);
1170+
const byteLen = buf.byteLength;
11561171
const fillLength = end - offset;
11571172
if (offset > end || fillLength + offset > byteLen)
11581173
throw new ERR_BUFFER_OUT_OF_BOUNDS();
@@ -1171,7 +1186,7 @@ function _fill(buf, value, offset, end, encoding) {
11711186
}
11721187

11731188
Buffer.prototype.write = function write(string, offset, length, encoding) {
1174-
const bufferLength = TypedArrayPrototypeGetLength(this);
1189+
const bufferLength = this.length;
11751190
// Buffer#write(string);
11761191
if (offset === undefined) {
11771192
return utf8Write(this, string, 0, bufferLength);
@@ -1212,7 +1227,7 @@ Buffer.prototype.write = function write(string, offset, length, encoding) {
12121227
};
12131228

12141229
Buffer.prototype.toJSON = function toJSON() {
1215-
const bufferLength = TypedArrayPrototypeGetLength(this);
1230+
const bufferLength = this.length;
12161231
if (bufferLength > 0) {
12171232
const data = new Array(bufferLength);
12181233
for (let i = 0; i < bufferLength; ++i)
@@ -1240,7 +1255,7 @@ function adjustOffset(offset, length) {
12401255
}
12411256

12421257
Buffer.prototype.subarray = function subarray(start, end) {
1243-
const srcLength = TypedArrayPrototypeGetLength(this);
1258+
const srcLength = this.length;
12441259
start = adjustOffset(start, srcLength);
12451260
end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
12461261
const newLength = end > start ? end - start : 0;
@@ -1262,7 +1277,7 @@ Buffer.prototype.swap16 = function swap16() {
12621277
// For Buffer.length <= 32, it's generally faster to
12631278
// do the swap in javascript. For larger buffers,
12641279
// dropping down to the native code is faster.
1265-
const len = TypedArrayPrototypeGetLength(this);
1280+
const len = this.length;
12661281
if (len % 2 !== 0)
12671282
throw new ERR_INVALID_BUFFER_SIZE('16-bits');
12681283
if (len <= 32) {
@@ -1279,7 +1294,7 @@ Buffer.prototype.swap32 = function swap32() {
12791294
// For Buffer.length <= 32, it's generally faster to
12801295
// do the swap in javascript. For larger buffers,
12811296
// dropping down to the native code is faster.
1282-
const len = TypedArrayPrototypeGetLength(this);
1297+
const len = this.length;
12831298
if (len % 4 !== 0)
12841299
throw new ERR_INVALID_BUFFER_SIZE('32-bits');
12851300
if (len <= 32) {
@@ -1300,7 +1315,7 @@ Buffer.prototype.swap64 = function swap64() {
13001315
// dropping down to the native code is faster.
13011316
// Threshold differs from swap16/swap32 (<=32) because swap64's
13021317
// crossover is between 40 and 48 (native wins at 48, loses at 40).
1303-
const len = TypedArrayPrototypeGetLength(this);
1318+
const len = this.length;
13041319
if (len % 8 !== 0)
13051320
throw new ERR_INVALID_BUFFER_SIZE('64-bits');
13061321
if (len < 48) {
@@ -1328,9 +1343,8 @@ if (internalBinding('config').hasIntl) {
13281343
// Transcodes the Buffer from one encoding to another, returning a new
13291344
// Buffer instance.
13301345
transcode = function transcode(source, fromEncoding, toEncoding) {
1331-
if (!isUint8Array(source)) {
1332-
throw new ERR_INVALID_ARG_TYPE('source',
1333-
['Buffer', 'Uint8Array'], source);
1346+
if (!ArrayBufferIsView(source) && !isAnyArrayBuffer(source)) {
1347+
throw new ERR_INVALID_ARG_TYPE('source', BUFFER_NAMES, source);
13341348
}
13351349
if (source.length === 0) return new FastBuffer();
13361350

@@ -1386,19 +1400,19 @@ function atob(input) {
13861400
}
13871401

13881402
function isUtf8(input) {
1389-
if (isTypedArray(input) || isAnyArrayBuffer(input)) {
1403+
if (isArrayBufferView(input) || isAnyArrayBuffer(input)) {
13901404
return bindingIsUtf8(input);
13911405
}
13921406

1393-
throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
1407+
throw new ERR_INVALID_ARG_TYPE('input', BUFFER_NAMES, input);
13941408
}
13951409

13961410
function isAscii(input) {
1397-
if (isTypedArray(input) || isAnyArrayBuffer(input)) {
1411+
if (isArrayBufferView(input) || isAnyArrayBuffer(input)) {
13981412
return bindingIsAscii(input);
13991413
}
14001414

1401-
throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
1415+
throw new ERR_INVALID_ARG_TYPE('input', BUFFER_NAMES, input);
14021416
}
14031417

14041418
module.exports = {

0 commit comments

Comments
 (0)