From 8a989d7bc84fba04387e0c8fe18aac50b774970c Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Tue, 22 Jul 2014 01:27:33 -0700 Subject: [PATCH] make IE10 use the Object implementation IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of incorrect length in some situations. --- index.js | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 73516cd..0d0d638 100644 --- a/index.js +++ b/index.js @@ -14,22 +14,35 @@ exports.INSPECT_MAX_BYTES = 50 Buffer.poolSize = 8192 /** - * If `Buffer._useTypedArrays`: + * If `TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (compatible down to IE6) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Note: + * + * - Implementation must support adding new properties to `Uint8Array` instances. + * Firefox 4-29 lacked support, fixed in Firefox 30+. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + * + * We detect these buggy browsers and set `TYPED_ARRAY_SUPPORT` to `false` so they will + * get the Object implementation, which is slower but will work correctly. */ -Buffer._useTypedArrays = (function () { - // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, - // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding - // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support - // because we need to be able to add all the node Buffer API methods. This is an issue - // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 +var TYPED_ARRAY_SUPPORT = (function () { try { var buf = new ArrayBuffer(0) var arr = new Uint8Array(buf) arr.foo = function () { return 42 } - return 42 === arr.foo() && - typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + return 42 === arr.foo() && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` } catch (e) { return false } @@ -69,7 +82,7 @@ function Buffer (subject, encoding, noZero) { throw new Error('First argument needs to be a number, array or string.') var buf - if (Buffer._useTypedArrays) { + if (TYPED_ARRAY_SUPPORT) { // Preferred: Return an augmented `Uint8Array` instance for best performance buf = Buffer._augment(new Uint8Array(length)) } else { @@ -80,7 +93,7 @@ function Buffer (subject, encoding, noZero) { } var i - if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + if (TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { // Speed optimization -- use set if we're copying from a typed array buf._set(subject) } else if (isArrayish(subject)) { @@ -94,7 +107,7 @@ function Buffer (subject, encoding, noZero) { } } else if (type === 'string') { buf.write(subject, 0, encoding) - } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + } else if (type === 'number' && !TYPED_ARRAY_SUPPORT && !noZero) { for (i = 0; i < length; i++) { buf[i] = 0 } @@ -401,7 +414,7 @@ Buffer.prototype.copy = function (target, target_start, start, end) { var len = end - start - if (len < 100 || !Buffer._useTypedArrays) { + if (len < 100 || !TYPED_ARRAY_SUPPORT) { for (var i = 0; i < len; i++) { target[i + target_start] = this[i + start] } @@ -495,7 +508,7 @@ Buffer.prototype.slice = function (start, end) { if (end < start) end = start - if (Buffer._useTypedArrays) { + if (TYPED_ARRAY_SUPPORT) { return Buffer._augment(this.subarray(start, end)) } else { var sliceLen = end - start @@ -954,7 +967,7 @@ Buffer.prototype.inspect = function () { */ Buffer.prototype.toArrayBuffer = function () { if (typeof Uint8Array !== 'undefined') { - if (Buffer._useTypedArrays) { + if (TYPED_ARRAY_SUPPORT) { return (new Buffer(this)).buffer } else { var buf = new Uint8Array(this.length) -- 2.34.1