diff --git a/lib/bufferreader.js b/lib/bufferreader.js index 15369fb..27fa495 100644 --- a/lib/bufferreader.js +++ b/lib/bufferreader.js @@ -87,7 +87,12 @@ BufferReader.prototype.readVarInt = function() { case 0xFE: return this.readUInt32LE(); case 0xFF: - throw new Error('number too large to retain precision - use readVarIntBN'); + var bn = this.readUInt64LEBN(); + var n = bn.toNumber(); + if (n <= Math.pow(2, 53)) + return n; + else + throw new Error('number too large to retain precision - use readVarIntBN'); default: return first; } diff --git a/test/bufferreader.js b/test/bufferreader.js index 3bbce17..670f9d6 100644 --- a/test/bufferreader.js +++ b/test/bufferreader.js @@ -1,6 +1,7 @@ var BufferWriter = require('../lib/bufferwriter'); var BufferReader = require('../lib/bufferreader'); var should = require('chai').should(); +var BN = require('../lib/bn'); describe('BufferReader', function() { @@ -188,14 +189,22 @@ describe('BufferReader', function() { br.readVarInt().should.equal(50000); }); - it('should throw an error on a 9 byte varint', function() { - var buf = Buffer.concat([new Buffer([255]), new Buffer('ffffffffffffffff', 'hex')]); + it('should throw an error on a 9 byte varint over the javascript uint precision limit', function() { + var buf = BufferWriter().writeVarIntBN(BN(Math.pow(2, 54).toString())).concat(); var br = new BufferReader({buf: buf}); (function() { br.readVarInt(); }).should.throw('number too large to retain precision - use readVarIntBN'); }); + it('should not throw an error on a 9 byte varint not over the javascript uint precision limit', function() { + var buf = BufferWriter().writeVarIntBN(BN(Math.pow(2, 53).toString())).concat(); + var br = new BufferReader({buf: buf}); + (function() { + br.readVarInt(); + }).should.not.throw('number too large to retain precision - use readVarIntBN'); + }); + }); describe('#readVarIntBN', function() {