Browse Source

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 <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
v7.x
Brian White 8 years ago
committed by James M Snell
parent
commit
73bafa0d81
  1. 9
      lib/buffer.js
  2. 6
      test/parallel/test-buffer-alloc.js
  3. 5
      test/parallel/test-buffer-bytelength.js

9
lib/buffer.js

@ -103,7 +103,7 @@ Buffer.from = function(value, encodingOrOffset, length) {
if (typeof value === 'number') if (typeof value === 'number')
throw new TypeError('"value" argument must not be a number'); throw new TypeError('"value" argument must not be a number');
if (value instanceof ArrayBuffer) if (isArrayBuffer(value))
return fromArrayBuffer(value, encodingOrOffset, length); return fromArrayBuffer(value, encodingOrOffset, length);
if (typeof value === 'string') if (typeof value === 'string')
@ -234,9 +234,6 @@ function fromArrayLike(obj) {
} }
function fromArrayBuffer(obj, byteOffset, length) { function fromArrayBuffer(obj, byteOffset, length) {
if (!isArrayBuffer(obj))
throw new TypeError('argument is not an ArrayBuffer');
byteOffset >>>= 0; byteOffset >>>= 0;
const maxLength = obj.byteLength - byteOffset; const maxLength = obj.byteLength - byteOffset;
@ -267,7 +264,7 @@ function fromObject(obj) {
} }
if (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) { if (typeof obj.length !== 'number' || obj.length !== obj.length) {
return new FastBuffer(); return new FastBuffer();
} }
@ -354,7 +351,7 @@ function base64ByteLength(str, bytes) {
function byteLength(string, encoding) { function byteLength(string, encoding) {
if (typeof string !== 'string') { if (typeof string !== 'string') {
if (ArrayBuffer.isView(string) || string instanceof ArrayBuffer) if (ArrayBuffer.isView(string) || isArrayBuffer(string))
return string.byteLength; return string.byteLength;
string = '' + string; string = '' + string;

6
test/parallel/test-buffer-alloc.js

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const assert = require('assert'); const assert = require('assert');
const vm = require('vm');
const Buffer = require('buffer').Buffer; const Buffer = require('buffer').Buffer;
const SlowBuffer = require('buffer').SlowBuffer; const SlowBuffer = require('buffer').SlowBuffer;
@ -1049,6 +1050,11 @@ assert.throws(() => {
// Regression test // Regression test
assert.doesNotThrow(() => Buffer.from(new ArrayBuffer())); 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 }), assert.throws(() => Buffer.alloc({ valueOf: () => 1 }),
/"size" argument must be a number/); /"size" argument must be a number/);
assert.throws(() => Buffer.alloc({ valueOf: () => -1 }), assert.throws(() => Buffer.alloc({ valueOf: () => -1 }),

5
test/parallel/test-buffer-bytelength.js

@ -4,6 +4,7 @@ require('../common');
const assert = require('assert'); const assert = require('assert');
const Buffer = require('buffer').Buffer; const Buffer = require('buffer').Buffer;
const SlowBuffer = require('buffer').SlowBuffer; const SlowBuffer = require('buffer').SlowBuffer;
const vm = require('vm');
// coerce values to string // coerce values to string
assert.strictEqual(Buffer.byteLength(32, 'latin1'), 2); 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) { ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
assert.strictEqual(24, Buffer.byteLength('Il était tué', 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);

Loading…
Cancel
Save