From 66e42ce37046014fd2b9d8f37ebfc14435e3cc7d Mon Sep 17 00:00:00 2001 From: Brian White <mscdex@mscdex.net> Date: Thu, 8 Sep 2016 18:31:39 -0400 Subject: [PATCH] buffer: fix ArrayBuffer checks This commit fixes detection of ArrayBuffers from different V8 contexts. This is especially a problem for environments like nw.js where the node and browser V8 contexts are not shared. --- lib/buffer.js | 9 +++------ test/parallel/test-buffer-alloc.js | 6 ++++++ test/parallel/test-buffer-bytelength.js | 5 +++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index b7e250da2d578c..cefec86e9abb67 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -103,7 +103,7 @@ Buffer.from = function(value, encodingOrOffset, length) { if (typeof value === 'number') throw new TypeError('"value" argument must not be a number'); - if (value instanceof ArrayBuffer) + if (isArrayBuffer(value)) return fromArrayBuffer(value, encodingOrOffset, length); if (typeof value === 'string') @@ -234,9 +234,6 @@ function fromArrayLike(obj) { } function fromArrayBuffer(obj, byteOffset, length) { - if (!isArrayBuffer(obj)) - throw new TypeError('argument is not an ArrayBuffer'); - byteOffset >>>= 0; const maxLength = obj.byteLength - byteOffset; @@ -267,7 +264,7 @@ function fromObject(obj) { } if (obj) { - if (obj.buffer instanceof ArrayBuffer || 'length' in obj) { + if (isArrayBuffer(obj.buffer) || 'length' in obj) { if (typeof obj.length !== 'number' || obj.length !== obj.length) { return new FastBuffer(); } @@ -354,7 +351,7 @@ function base64ByteLength(str, bytes) { function byteLength(string, encoding) { if (typeof string !== 'string') { - if (ArrayBuffer.isView(string) || string instanceof ArrayBuffer) + if (ArrayBuffer.isView(string) || isArrayBuffer(string)) return string.byteLength; string = '' + string; diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index c80ee10382a968..231b1b61fa2c72 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -1,6 +1,7 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); +const vm = require('vm'); const Buffer = require('buffer').Buffer; const SlowBuffer = require('buffer').SlowBuffer; @@ -1049,6 +1050,11 @@ assert.throws(() => { // Regression test assert.doesNotThrow(() => Buffer.from(new ArrayBuffer())); +// Test that ArrayBuffer from a different context is detected correctly +const arrayBuf = vm.runInNewContext('new ArrayBuffer()'); +assert.doesNotThrow(() => Buffer.from(arrayBuf)); +assert.doesNotThrow(() => Buffer.from({ buffer: arrayBuf })); + assert.throws(() => Buffer.alloc({ valueOf: () => 1 }), /"size" argument must be a number/); assert.throws(() => Buffer.alloc({ valueOf: () => -1 }), diff --git a/test/parallel/test-buffer-bytelength.js b/test/parallel/test-buffer-bytelength.js index 521cff7d3bd16a..14d7c95dd231aa 100644 --- a/test/parallel/test-buffer-bytelength.js +++ b/test/parallel/test-buffer-bytelength.js @@ -4,6 +4,7 @@ require('../common'); const assert = require('assert'); const Buffer = require('buffer').Buffer; const SlowBuffer = require('buffer').SlowBuffer; +const vm = require('vm'); // coerce values to string assert.strictEqual(Buffer.byteLength(32, 'latin1'), 2); @@ -87,3 +88,7 @@ assert.strictEqual(Buffer.byteLength('Il était tué', 'binary'), 12); ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) { assert.strictEqual(24, Buffer.byteLength('Il était tué', encoding)); }); + +// Test that ArrayBuffer from a different context is detected correctly +const arrayBuf = vm.runInNewContext('new ArrayBuffer()'); +assert.strictEqual(Buffer.byteLength(arrayBuf), 0);