From ee2d44a7050695b14b7b9a44778e4eb59f6e8a1d Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Mon, 20 Mar 2017 23:56:04 -0700 Subject: [PATCH] buffer: stricter Buffer.isBuffer Make "fake" Buffer subclasses whose instances are not valid Uint8Arrays fail the test. Fixes: https://github.com/nodejs/node/issues/11954 --- lib/buffer.js | 9 +++++++- test/parallel/test-buffer-isbuffer.js | 31 +++++++++++++++++++++++++++ test/parallel/test-util.js | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-buffer-isbuffer.js diff --git a/lib/buffer.js b/lib/buffer.js index fff7485cb004f6..ae690bb9874db6 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -420,7 +420,14 @@ function fromObject(obj) { // Static methods Buffer.isBuffer = function isBuffer(b) { - return b instanceof Buffer; + if (!isUint8Array(b)) + return false; + // Subclassing Buffer is not officially supported currently, and actually + // subclassing it requires some awkward code that users are unlikely to do. + // Therefore prioritize the fast case over the full `instanceof`. + // Refs: https://github.com/nodejs/node/issues/9531#issuecomment-265611061 + const proto = Object.getPrototypeOf(b); + return proto === Buffer.prototype || proto instanceof Buffer.prototype; }; diff --git a/test/parallel/test-buffer-isbuffer.js b/test/parallel/test-buffer-isbuffer.js new file mode 100644 index 00000000000000..246fb0817661b0 --- /dev/null +++ b/test/parallel/test-buffer-isbuffer.js @@ -0,0 +1,31 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const { Buffer } = require('buffer'); + +const t = (val, exp) => assert.strictEqual(Buffer.isBuffer(val), exp); + +function FakeBuffer() {} +FakeBuffer.prototype = Object.create(Buffer.prototype); + +class ExtensibleBuffer extends Buffer { + constructor() { + super(new ArrayBuffer(0), 0, 0); + Object.setPrototypeOf(this, new.target.prototype); + } +} + +t(0, false); +t(true, false); +t('foo', false); +t(Symbol(), false); +t(null, false); +t(undefined, false); +t(() => {}, false); + +t({}, false); +t(new Uint8Array(2), false); +t(new FakeBuffer(), false); +t(new ExtensibleBuffer(), true); +t(Buffer.from('foo'), true); +t(Buffer.allocUnsafeSlow(2), true); diff --git a/test/parallel/test-util.js b/test/parallel/test-util.js index 3b2729c107b4b1..1f9a6ef34e8676 100644 --- a/test/parallel/test-util.js +++ b/test/parallel/test-util.js @@ -96,6 +96,7 @@ assert.strictEqual(true, util.isPrimitive(NaN)); assert.strictEqual(true, util.isPrimitive(Symbol('symbol'))); // isBuffer +assert.strictEqual(util.isBuffer, Buffer.isBuffer); assert.strictEqual(false, util.isBuffer('foo')); assert.strictEqual(true, util.isBuffer(Buffer.from('foo')));