Skip to content

Commit

Permalink
simplify _create(), return nothing from _install/_uninstall, fix 0-le…
Browse files Browse the repository at this point in the history
…ngth alloc, cleanups
  • Loading branch information
andrasq committed Feb 22, 2019
1 parent 5285f18 commit ab8e1ee
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -7,6 +7,7 @@ sane-buffer
Fix the `Buffer` constructor semantics to not break legacy code. Unlike packages that
polyfill the new API, this one polyfills both new (for older nodejs that is missing calls or whose
calls behaved differently) and the old (for new nodejs that deprecated them).
Also fixes the unexpected "argument must not be a number" error from `Buffer.from(new Number(3))`.

The module wrappers `Buffer` to support the old constructor API. Safe behavior can be
preserved by setting `require('sane-buffer').safe = true`. The wrapper can be installed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -11,7 +11,7 @@
"scripts": {
"prepublishOnly": "mv .trav* test.js .git/ar",
"postpublish": "mv .git/ar/.trav* .git/ar/test.js .",
"test": "pwd ; ls -ls ; qnit test*.js",
"test": "qnit test*.js",
"coverage": "nyc -r text -r lcov npm test",
"clean": "rm -rf .nyc_output/ coverage/ npm-debug.log"
}
Expand Down
27 changes: 10 additions & 17 deletions sane-buffer.js
Expand Up @@ -17,15 +17,14 @@ var nodeVersion = parseInt(process.version.slice(1)); // version is mocked by
module.exports = OBuffer;

function OBuffer( arg, encOrOffs, length ) {
// create as type Buffer, but patch it up to make it appear instanceof OBuffer
return _typeconvert(OBuffer._create(arg, encOrOffs, length));
}
util.inherits(OBuffer, Buffer);

// wrapper instance builder methods too (do after the inerits, old node clears prototype)
OBuffer.prototype.slice = function(base, bound) { return _typeconvert(Buffer.prototype.slice.call(this, base, bound)) };

// copy class methods
// copy class methods and properties
for (var k in Buffer) OBuffer[k] = Buffer[k];
OBuffer.Buffer = OBuffer;
OBuffer._Buffer = Buffer;
Expand All @@ -34,28 +33,20 @@ OBuffer._Buffer = Buffer;
OBuffer.from = _typewrapper('from', function(a, b, c) { return new OBuffer(a, b, c) });
OBuffer.alloc = _typewrapper('alloc', function(n) { return _fill0(new OBuffer(n)) });
OBuffer.allocUnsafe = _typewrapper('allocUnsafe', function(n) { return new OBuffer(n) });
// patch returned Buffers to make them appear instanceof OBuffer
OBuffer.allocUnsafeSlow = (nodeVersion >= 6 && Buffer.allocUnsafeSlow) ? function(size) { return _typeconvert(Buffer.allocUnsafeSlow(size)) } : undefined;
OBuffer.concat = function(list, length) { return _typeconvert(Buffer.concat(list, length)) };

// class properties and class methods
OBuffer._safe = false;
OBuffer._install = function() { return global.Buffer = OBuffer }
OBuffer._uninstall = function() { global.Buffer = Buffer; return OBuffer }
OBuffer._install = function() { global.Buffer = OBuffer }
OBuffer._uninstall = function() { global.Buffer = Buffer }
OBuffer._create = function _create( arg, encOrOffs, length ) {
// node through v9 supported the old constructor semantics, 10 and up deprecate it
if (nodeVersion < 10) {
if (OBuffer.safe && arg && arg.constructor === Number) return _fill0(new Buffer(arg));
return new Buffer(arg, encOrOffs, length);
}

if (arg != null) {
if (arg.constructor === String) return Buffer.from(arg, encOrOffs);
else if (arg.constructor === Number) return OBuffer.safe ? Buffer.alloc(arg) : Buffer.allocUnsafe(arg);
else if (arg instanceof Array || arg instanceof Buffer || arg && arg.length !== undefined) return Buffer.from(arg);
}
// handle everything else, including no-args errors, by the implementation (eg node-v8.2 allows objects)
return new Buffer.from(arg, encOrOffs, length);
return (
(nodeVersion < 10) ? (OBuffer.safe && _isNumber(arg)) ? _fill0(new Buffer(arg)) : new Buffer(arg, encOrOffs, length) :
_isNumber(arg) ? (OBuffer.safe ? Buffer.alloc(arg) : Buffer.allocUnsafe(arg)) :
Buffer.from(arg, encOrOffs, length)
)
}

// monkeypatch the object to make it intanceof OBuffer
Expand All @@ -66,3 +57,5 @@ function _typewrapper(name, poly) { return (nodeVersion >= 6 && Buffer[name]) ?

// polyfill for .fill(0)
function _fill0(buf) { var len = buf.length; for (var i=0; i<len; i++) buf[i] = 0; return buf }

function _isNumber(x) { return x != null && x.constructor === Number }
8 changes: 8 additions & 0 deletions test.js
Expand Up @@ -191,6 +191,14 @@ module.exports = {
t.ok(buf instanceof SysBuffer);
t.equal(buf.length, 7);

var buf = OBuffer.alloc(0);
t.ok(buf instanceof SysBuffer);
t.equal(buf.length, 0);

var buf = OBuffer.allocUnsafe(0);
t.ok(buf instanceof SysBuffer);
t.equal(buf.length, 0);

OBuffer.safe = true;
var buf = new OBuffer(777);
t.equal(buf.length, 777);
Expand Down

0 comments on commit ab8e1ee

Please sign in to comment.