Skip to content

Commit

Permalink
fix(decoder): handle large input sizes
Browse files Browse the repository at this point in the history
Fixes #10
  • Loading branch information
dignifiedquire committed Dec 14, 2016
1 parent f0656ff commit b44cdfe
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}

Expand All @@ -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)
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
25 changes: 25 additions & 0 deletions test/decoder.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
11 changes: 11 additions & 0 deletions test/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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])
})
})
})

0 comments on commit b44cdfe

Please sign in to comment.