diff --git a/src/util.js b/src/util.js index cfb5c20..8d3125b 100644 --- a/src/util.js +++ b/src/util.js @@ -153,9 +153,14 @@ exports.deserialize = (data) => { throw new Error('Data is too large to deserialize with current decoder') } - const deserialized = decoder.decodeFirst(data) + // borc will decode back-to-back objects into an implicit top-level array, we + // strictly want to only see a single explicit top-level object + const all = decoder.decodeAll(data) + if (all.length !== 1) { + throw new Error('Extraneous CBOR data found beyond initial top-level object') + } - return deserialized + return all[0] } /** diff --git a/test/util.spec.js b/test/util.spec.js index e065481..37c3ea0 100644 --- a/test/util.spec.js +++ b/test/util.spec.js @@ -122,4 +122,12 @@ describe('util', () => { expect(dagCBOR.util.deserialize(s1)).to.be.eql({ data: bytes }) expect(dagCBOR.util.deserialize(s2)).to.be.eql({ data: bytes }) }) + + it('reject extraneous, but valid CBOR data after initial top-level object', () => { + expect(() => + // two top-level CBOR objects, the original and a single uint=0, valid if using + // CBOR in streaming mode, not valid here + dagCBOR.util.deserialize(Buffer.concat([serializedObj, Buffer.alloc(1)])) + ).to.throw(Error, 'Extraneous CBOR data found beyond initial top-level object') + }) })