diff --git a/lib/buffer.js b/lib/buffer.js index 01b9ea97f95a68..5a6b75c33e5be6 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -34,9 +34,12 @@ const { ObjectCreate, ObjectDefineProperties, ObjectDefineProperty, + ObjectGetOwnPropertyDescriptor, + ObjectGetPrototypeOf, ObjectSetPrototypeOf, SymbolSpecies, SymbolToPrimitive, + Uint8ArrayPrototype, } = primordials; const { @@ -101,6 +104,13 @@ const { addBufferPrototypeMethods } = require('internal/buffer'); +const TypedArrayPrototype = ObjectGetPrototypeOf(Uint8ArrayPrototype); + +const TypedArrayProto_byteLength = + ObjectGetOwnPropertyDescriptor(TypedArrayPrototype, + 'byteLength').get; +const TypedArrayFill = TypedArrayPrototype.fill; + FastBuffer.prototype.constructor = Buffer; Buffer.prototype = FastBuffer.prototype; addBufferPrototypeMethods(Buffer.prototype); @@ -1001,11 +1011,22 @@ function _fill(buf, value, offset, end, encoding) { return buf; } - const res = bindingFill(buf, value, offset, end, encoding); - if (res < 0) { - if (res === -1) - throw new ERR_INVALID_ARG_VALUE('value', value); - throw new ERR_BUFFER_OUT_OF_BOUNDS(); + + if (typeof value === 'number') { + // OOB check + const byteLen = TypedArrayProto_byteLength.call(buf); + const fillLength = end - offset; + if (offset > end || fillLength + offset > byteLen) + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + + TypedArrayFill.call(buf, value, offset, end); + } else { + const res = bindingFill(buf, value, offset, end, encoding); + if (res < 0) { + if (res === -1) + throw new ERR_INVALID_ARG_VALUE('value', value); + throw new ERR_BUFFER_OUT_OF_BOUNDS(); + } } return buf;