From b9bdf21cbe67074c119b4cbdffd11b38532d665b Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Sat, 31 May 2014 13:18:57 +1000 Subject: [PATCH] bufferutils: use verifuint for 64 bit integers Taken from browserify-buffer. Also adds a few more tests to assert this is working correctly from both read and write perspectives. The assertion in for writePushDataInt in the 32 bit case was unnecessary as that is handled by buffer.writeUInt32LE anyway. --- src/bufferutils.js | 20 ++++++++++---------- test/bufferutils.js | 35 ++++++++++++++++++++++------------- test/fixtures/buffer.json | 10 ++++++++-- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/bufferutils.js b/src/bufferutils.js index ac340e9..e24735f 100644 --- a/src/bufferutils.js +++ b/src/bufferutils.js @@ -1,6 +1,14 @@ var assert = require('assert') var opcodes = require('./opcodes') +// https://github.com/feross/buffer/blob/master/index.js#L1127 +function verifuint(value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + function pushDataSize(i) { return i < opcodes.OP_PUSHDATA1 ? 1 : i < 0xff ? 2 @@ -47,9 +55,7 @@ function readUInt64LE(buffer, offset) { var b = buffer.readUInt32LE(offset + 4) b *= 0x100000000 - // Javascript Safe Integer limitation - // assert(Number.isSafeInteger(value), 'value must be < 2^53') - assert(b + a < 0x0020000000000000, 'value must be < 2^53') + verifuint(b + a, 0x001fffffffffffff) return b + a } @@ -104,10 +110,6 @@ function writePushDataInt(buffer, number, offset) { // 32 bit } else { - // Javascript Safe Integer limitation - // assert(Number.isSafeInteger(value), 'value must be < 2^53') - assert(number < 0x0020000000000000, 'value must be < 2^53') - buffer.writeUInt8(opcodes.OP_PUSHDATA4, offset) buffer.writeUInt32LE(number, offset + 1) @@ -117,9 +119,7 @@ function writePushDataInt(buffer, number, offset) { } function writeUInt64LE(buffer, value, offset) { - // Javascript Safe Integer limitation - // assert(Number.isSafeInteger(value), 'value must be < 2^53') - assert(value < 0x0020000000000000, 'value must be < 2^53') + verifuint(value, 0x001fffffffffffff) buffer.writeInt32LE(value & -1, offset) buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4) diff --git a/test/bufferutils.js b/test/bufferutils.js index 72cec2d..d56dbcd 100644 --- a/test/bufferutils.js +++ b/test/bufferutils.js @@ -39,6 +39,16 @@ describe('bufferutils', function() { assert.equal(number, f.dec) }) }) + + fixtures.invalid.forEach(function(f) { + it('throws on ' + f.description, function() { + var buffer = new Buffer(f.hex64, 'hex') + + assert.throws(function() { + bufferutils.readUInt64LE(buffer, 0) + }, new RegExp(f.exception)) + }) + }) }) describe('readVarInt', function() { @@ -51,6 +61,16 @@ describe('bufferutils', function() { assert.equal(d.size, buffer.length) }) }) + + fixtures.invalid.forEach(function(f) { + it('throws on ' + f.description, function() { + var buffer = new Buffer(f.hexVI, 'hex') + + assert.throws(function() { + bufferutils.readVarInt(buffer, 0) + }, new RegExp(f.exception)) + }) + }) }) describe('varIntSize', function() { @@ -75,17 +95,6 @@ describe('bufferutils', function() { assert.equal(buffer.slice(0, n).toString('hex'), f.hexPD) }) }) - - fixtures.invalid.forEach(function(f) { - it('throws on ' + f.description, function() { - var buffer = new Buffer(5) - buffer.fill(0) - - assert.throws(function() { - bufferutils.writePushDataInt(buffer, f.dec, 0) - }, /value must be < 2\^53/) - }) - }) }) describe('writeUInt64LE', function() { @@ -106,7 +115,7 @@ describe('bufferutils', function() { assert.throws(function() { bufferutils.writeUInt64LE(buffer, f.dec, 0) - }, /value must be < 2\^53/) + }, new RegExp(f.exception)) }) }) }) @@ -129,7 +138,7 @@ describe('bufferutils', function() { assert.throws(function() { bufferutils.writeVarInt(buffer, f.dec, 0) - }, /value must be < 2\^53/) + }, new RegExp(f.exception)) }) }) }) diff --git a/test/fixtures/buffer.json b/test/fixtures/buffer.json index 116e70a..8c6881d 100644 --- a/test/fixtures/buffer.json +++ b/test/fixtures/buffer.json @@ -85,11 +85,17 @@ "invalid": [ { "description": "n === 2^53", - "value": 9007199254740992 + "exception": "value is larger than maximum value for type", + "hex64": "0000000000002000", + "hexVI": "ff0000000000000020", + "dec": 9007199254740992 }, { "description": "n > 2^53", - "value": 18374686479671624000 + "exception": "value is larger than maximum value for type", + "hex64": "0100000000002000", + "hexVI": "ff0100000000000020", + "dec": 9007199254740993 } ] }