From 2ab3c5d309459b623dd6ff028606ccb8a5edd920 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Sun, 29 Nov 2015 07:04:08 -0600 Subject: [PATCH] patchIssue3992: decouple from Layout module Provide the patch for Node.js issue #3992 as a standalone module. See: nodejs/node#3992 --- README.md | 5 +- lib/Layout.js | 73 +-------------------------- lib/patchIssue3992.js | 111 ++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 4 files changed, 116 insertions(+), 75 deletions(-) create mode 100644 lib/patchIssue3992.js diff --git a/README.md b/README.md index 43ca692..ccc3164 100644 --- a/README.md +++ b/README.md @@ -276,5 +276,6 @@ decoding each of the alternatives: **NOTE** This code tickles a long-standing [bug in Buffer.writeInt{L,B}E](https://github.com/nodejs/node/pull/3994). `buffer-layout` -patches `Buffer` to fix the bug if it detects that the running Node has -has the error. +provides a [module that patches +`Buffer`](http://pabigot.github.io/buffer-layout/module-patchIssue3992.html) +to fix the bug if it detects that the running Node has the error. diff --git a/lib/Layout.js b/lib/Layout.js index 230636d..6634db5 100644 --- a/lib/Layout.js +++ b/lib/Layout.js @@ -121,78 +121,7 @@ var assert = require('assert'); -/* Determine whether node issue #3992 is fixed, and if not replace the - * Buffer functions with ones that work correctly. - * - * See: https://github.com/nodejs/node/issues/3992 */ -var issue_3992_is_resolved = (function () { - var buf = new Buffer(2); - buf.writeIntLE(-0x100, 0, 2); - return (0xFF === buf[1]); -})(); -/* NB: Backfill code modified from node lib/buffer.js as of - * 8bc80386879538de63cd6f2aef288f59324eb004 (2015-11-20) */ -/* istanbul ignore next */ -function checkInt(buffer, value, offset, ext, max, min) { - if (!(buffer instanceof Buffer)) - throw new TypeError('"buffer" argument must be a Buffer instance'); - if (value > max || value < min) - throw new TypeError('"value" argument is out of bounds'); - if (offset + ext > buffer.length) - throw new RangeError('Index out of range'); -} -/* The grotesquery here is because jshint whines about strict mode - * violations if the function doesn't appear to be a method, and about - * defining functions within a block if the test is in an if - * statement. */ -Buffer.prototype.writeIntLE = issue_3992_is_resolved ? Buffer.prototype.writeIntLE : function(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) { - checkInt(this, - value, - offset, - byteLength, - Math.pow(2, 8 * byteLength - 1) - 1, - -Math.pow(2, 8 * byteLength - 1)); - } - - var i = 0; - var mul = 1; - var sub = 0; - this[offset] = value; - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) - sub = 1; - this[offset + i] = ((value / mul) >> 0) - sub; - } - - return offset + byteLength; -}; -Buffer.prototype.writeIntBE = issue_3992_is_resolved ? Buffer.prototype.writeIntBE : function(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) { - checkInt(this, - value, - offset, - byteLength, - Math.pow(2, 8 * byteLength - 1) - 1, - -Math.pow(2, 8 * byteLength - 1)); - } - - var i = byteLength - 1; - var mul = 1; - var sub = 0; - this[offset + i] = value; - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) - sub = 1; - this[offset + i] = ((value / mul) >> 0) - sub; - } - - return offset + byteLength; -}; +require('./patchIssue3992'); /* istanbul ignore next */ /* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger */ diff --git a/lib/patchIssue3992.js b/lib/patchIssue3992.js new file mode 100644 index 0000000..a1a75b1 --- /dev/null +++ b/lib/patchIssue3992.js @@ -0,0 +1,111 @@ +/* Material in this file modified from Node.js under LICENSE: + +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + */ + +/** Determine whether {@link + * https://github.com/nodejs/node/issues/3992|Node.js issue #3992} is + * fixed, and if not replace the Buffer functions with ones that work + * correctly. + * + * This module exports no behavior. It may modify the Buffer + * prototype. + * + * This module originates from {@link + * https://github.com/pabigot/buffer-layout|buffer-layout on GitHub}. + * + * @module patchIssue3992 + * @license MIT + */ + +/* Test whether Buffer.writeIntLE() gets the right answer for + * problematic negative integers */ +var issue_3992_is_resolved = (function () { + var buf = new Buffer(2); + buf.writeIntLE(-0x100, 0, 2); + // The value would be 0xFE if the bug is present + return (0xFF === buf[1]); +})(); + +/* NB: Backfill code modified from node lib/buffer.js as of + * 8bc80386879538de63cd6f2aef288f59324eb004 (2015-11-20) */ +/* istanbul ignore next */ +function checkInt(buffer, value, offset, ext, max, min) { + if (!(buffer instanceof Buffer)) + throw new TypeError('"buffer" argument must be a Buffer instance'); + if (value > max || value < min) + throw new TypeError('"value" argument is out of bounds'); + if (offset + ext > buffer.length) + throw new RangeError('Index out of range'); +} + +/* The grotesquery here is because jshint whines about strict mode + * violations if the function doesn't appear to be a method, and about + * defining functions within a block if the test is in an if + * statement. */ +Buffer.prototype.writeIntLE = issue_3992_is_resolved ? Buffer.prototype.writeIntLE : function(value, offset, byteLength, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + checkInt(this, + value, + offset, + byteLength, + Math.pow(2, 8 * byteLength - 1) - 1, + -Math.pow(2, 8 * byteLength - 1)); + } + + var i = 0; + var mul = 1; + var sub = 0; + this[offset] = value; + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) + sub = 1; + this[offset + i] = ((value / mul) >> 0) - sub; + } + + return offset + byteLength; +}; + +Buffer.prototype.writeIntBE = issue_3992_is_resolved ? Buffer.prototype.writeIntBE : function(value, offset, byteLength, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + checkInt(this, + value, + offset, + byteLength, + Math.pow(2, 8 * byteLength - 1) - 1, + -Math.pow(2, 8 * byteLength - 1)); + } + + var i = byteLength - 1; + var mul = 1; + var sub = 0; + this[offset + i] = value; + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) + sub = 1; + this[offset + i] = ((value / mul) >> 0) - sub; + } + + return offset + byteLength; +}; diff --git a/package.json b/package.json index 3447c02..ebdb24c 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "coverage": "istanbul cover _mocha -- -u tdd", "coveralls": "istanbul cover _mocha --report lcovonly -- -u tdd && cat ./coverage/lcov.info | coveralls", "jslint": "jslint lib/Layout.js || true", - "lint": "jshint lib/Layout.js test/*.js || true", + "lint": "jshint lib/*.js test/*.js || true", "lint.strict": "jshint lib/Layout.js", "mkdoc": "jsdoc -c jsdoc/conf.json", "test": "mocha -u tdd"