diff --git a/src/decoder.js b/src/decoder.js index 8ae7a52b..db403ccf 100644 --- a/src/decoder.js +++ b/src/decoder.js @@ -23,6 +23,9 @@ class Decoder { if (!opts.size || opts.size < 0x10000) { opts.size = 0x10000 + } else { + // Ensure the size is a power of 2 + opts.size = utils.nextPowerOf2(opts.size) } // Heap use to share the input with the parser @@ -593,7 +596,7 @@ class Decoder { input = new Buffer(input, enc || 'hex') } - const dec = new Decoder() + const dec = new Decoder({size: input.length}) return dec.decodeFirst(input) } @@ -609,7 +612,7 @@ class Decoder { input = new Buffer(input, enc || 'hex') } - const dec = new Decoder() + const dec = new Decoder({size: input.length}) return dec.decodeAll(input) } } diff --git a/src/utils.js b/src/utils.js index 2ecfcebb..2084db24 100644 --- a/src/utils.js +++ b/src/utils.js @@ -155,3 +155,19 @@ exports.keySorter = function (a, b) { exports.isNegativeZero = (x) => { return x === 0 && (1 / x < 0) } + +exports.nextPowerOf2 = (n) => { + let count = 0 + // First n in the below condition is for + // the case where n is 0 + if (n && !(n & (n - 1))) { + return n + } + + while (n !== 0) { + n >>= 1 + count += 1 + } + + return 1 << count +} diff --git a/test/decoder.spec.js b/test/decoder.spec.js index b3fefb4c..89e13ad1 100644 --- a/test/decoder.spec.js +++ b/test/decoder.spec.js @@ -101,6 +101,31 @@ describe('Decoder', function () { ).to.throw() }) + it('decodeFirst large input', () => { + const largeInput = [] + for (let i = 0; i < 0x10000; i++) { + largeInput.push('hi') + } + + expect( + cbor.decodeFirst(cbor.encode(largeInput)) + ).to.be.eql( + largeInput + ) + }) + + it('decodeAll large input', () => { + const largeInput = [] + for (let i = 0; i < 0x10000; i++) { + largeInput.push('hi') + } + + expect( + cbor.decodeAll(cbor.encode(largeInput)) + ).to.be.eql( + [largeInput] + ) + }) // TODO: implement depth limit it.skip('depth', () => { expect( diff --git a/test/utils.spec.js b/test/utils.spec.js index d859269d..a3c55c97 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -73,4 +73,15 @@ describe('utils', () => { expect(utils.isNegativeZero(12.5)).to.be.eql(false) expect(utils.isNegativeZero(-Infinity)).to.be.eql(false) }) + + it('nextPowerOf2', () => { + [ + [1, 1], + [5, 8], + [127, 128], + [129, 256] + ].forEach((test) => { + expect(utils.nextPowerOf2(test[0])).to.be.eql(test[1]) + }) + }) })