From 1849c2cc999da5c30d2a4497abbcf06a4ba88394 Mon Sep 17 00:00:00 2001 From: Brian White Date: Fri, 24 Jan 2020 02:44:15 -0500 Subject: [PATCH] buffer: improve fill(number) performance PR-URL: https://github.com/nodejs/node/pull/31489 Reviewed-By: Ben Noordhuis Reviewed-By: Rich Trott Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Ruben Bridgewater --- lib/buffer.js | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) 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;