From 6e3db283edfe6ec9f0593fc0e68bf3fc4524e150 Mon Sep 17 00:00:00 2001 From: Brian White 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. PR-URL: https://github.com/nodejs/node/pull/8453 Reviewed-By: Anna Henningsen Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Sakthipriyan Vairamani Conflicts: test/parallel/test-buffer-alloc.js --- 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 2e148201e8f4be..a4d14305f7ad68 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -88,7 +88,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') @@ -212,9 +212,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; @@ -245,7 +242,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(); } @@ -332,7 +329,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 3e6bc1736cdc5d..e20db561c68a6f 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; @@ -1078,3 +1079,8 @@ 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 })); 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);