Skip to content

Commit

Permalink
Merge pull request #189 from hildjj/add-preferMap
Browse files Browse the repository at this point in the history
Fix #186.  Add preferMap to decode options
  • Loading branch information
hildjj authored Jan 31, 2024
2 parents 9733408 + 596afd9 commit 88781a0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
19 changes: 16 additions & 3 deletions packages/cbor/lib/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class UnexpectedDataError extends Error {
* @property {Tagged.TagMap} [tags] Mapping from tag number to function(v),
* where v is the decoded value that comes after the tag, and where the
* function returns the correctly-created value for that tag.
* @property {boolean} [preferMap=false] If true, prefer to generate Map
* instances to plain objects, even if there are no entries in the map
* or if all of the keys are strings.
* @property {boolean} [preferWeb=false] If true, prefer Uint8Arrays to
* be generated instead of node Buffers. This might turn on some more
* changes in the future, so forward-compatibility is not guaranteed yet.
Expand Down Expand Up @@ -127,6 +130,7 @@ class Decoder extends BinaryParseStream {
const {
tags = {},
max_depth = -1,
preferMap = false,
preferWeb = false,
required = false,
encoding = 'hex',
Expand All @@ -140,6 +144,7 @@ class Decoder extends BinaryParseStream {
this.running = true
this.max_depth = max_depth
this.tags = tags
this.preferMap = preferMap
this.preferWeb = preferWeb
this.extendedResults = extendedResults
this.required = required
Expand Down Expand Up @@ -515,7 +520,11 @@ class Decoder extends BinaryParseStream {
case MT.MAP:
switch (val) {
case 0:
val = (mt === MT.MAP) ? {} : []
if (mt === MT.MAP) {
val = (this.preferMap) ? new Map() : {}
} else {
val = []
}
break
case -1:
this.emit('start', mt, SYMS.STREAM, parent_major, parent_length)
Expand Down Expand Up @@ -583,12 +592,16 @@ class Decoder extends BinaryParseStream {
val = parent
break
case MT.MAP: {
let allstrings = true
let allstrings = !this.preferMap

if ((parent.length % 2) !== 0) {
throw new Error(`Invalid map length: ${parent.length}`)
}
for (let i = 0, len = parent.length; i < len; i += 2) {
for (
let i = 0, len = parent.length;
allstrings && (i < len);
i += 2
) {
if ((typeof parent[i] !== 'string') ||
(parent[i] === '__proto__')) {
allstrings = false
Expand Down
22 changes: 22 additions & 0 deletions packages/cbor/test/decoder.ava.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,25 @@ test('duplicate map keys', t => {

t.throws(() => cbor.decode(Buffer.from('a268746f537472696e670068746f537472696e6701', 'hex'), {preventDuplicateKeys: true}))
})

test('preferMap', t => {
t.deepEqual(
cbor.decode(Buffer.from('a0', 'hex'), {preferMap: false}),
{}
)

t.deepEqual(
cbor.decode(Buffer.from('a0', 'hex'), {preferMap: true}),
new Map()
)

t.deepEqual(
cbor.decode(Buffer.from('a161616161', 'hex'), {preferMap: false}),
{a: 'a'}
)

t.deepEqual(
cbor.decode(Buffer.from('a161616161', 'hex'), {preferMap: true}),
new Map([['a', 'a']])
)
})

0 comments on commit 88781a0

Please sign in to comment.