cbor-x 1.5.9 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -7
- package/decode.d.ts +1 -1
- package/decode.js +51 -7
- package/dist/decode-no-eval.cjs +49 -7
- package/dist/decode-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.cjs +74 -13
- package/dist/index-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.min.js +1 -1
- package/dist/index-no-eval.min.js.map +1 -1
- package/dist/index.js +74 -13
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +75 -13
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +102 -20
- package/dist/test.js.map +1 -1
- package/encode.js +26 -6
- package/index.d.ts +6 -1
- package/index.js +1 -1
- package/node-index.js +1 -1
- package/package.json +2 -2
package/dist/test.js
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
const BUNDLED_STRINGS_ID = 0xdff9;
|
|
16
16
|
const PACKED_REFERENCE_TAG_ID = 6;
|
|
17
17
|
const STOP_CODE = {};
|
|
18
|
+
let maxArraySize = 112810000; // This is the maximum array size in V8. We would potentially detect and set it higher
|
|
19
|
+
// for JSC, but this is pretty large and should be sufficient for most use cases
|
|
20
|
+
let maxMapSize = 16810000; // JavaScript has a fixed maximum map size of about 16710000, but JS itself enforces this,
|
|
21
|
+
// many keys in an object, so also probably a reasonable choice there.
|
|
18
22
|
let strings = EMPTY_ARRAY;
|
|
19
23
|
let stringPosition = 0;
|
|
20
24
|
let currentDecoder = {};
|
|
@@ -263,6 +267,7 @@
|
|
|
263
267
|
}
|
|
264
268
|
token = dataView.getUint32(position$1);
|
|
265
269
|
position$1 += 4;
|
|
270
|
+
if (majorType === 1) return -1 - token; // can't safely use negation operator here
|
|
266
271
|
break
|
|
267
272
|
case 0x1b:
|
|
268
273
|
if (majorType == 7) {
|
|
@@ -277,8 +282,7 @@
|
|
|
277
282
|
} else if (currentDecoder.int64AsNumber) {
|
|
278
283
|
token = dataView.getUint32(position$1) * 0x100000000;
|
|
279
284
|
token += dataView.getUint32(position$1 + 4);
|
|
280
|
-
} else
|
|
281
|
-
token = dataView.getBigUint64(position$1);
|
|
285
|
+
} else token = dataView.getBigUint64(position$1);
|
|
282
286
|
position$1 += 8;
|
|
283
287
|
break
|
|
284
288
|
case 0x1f:
|
|
@@ -291,6 +295,7 @@
|
|
|
291
295
|
let array = [];
|
|
292
296
|
let value, i = 0;
|
|
293
297
|
while ((value = read()) != STOP_CODE) {
|
|
298
|
+
if (i >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
294
299
|
array[i++] = value;
|
|
295
300
|
}
|
|
296
301
|
return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
|
|
@@ -298,8 +303,19 @@
|
|
|
298
303
|
let key;
|
|
299
304
|
if (currentDecoder.mapsAsObjects) {
|
|
300
305
|
let object = {};
|
|
301
|
-
|
|
302
|
-
|
|
306
|
+
let i = 0;
|
|
307
|
+
if (currentDecoder.keyMap) {
|
|
308
|
+
while((key = read()) != STOP_CODE) {
|
|
309
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
310
|
+
object[safeKey(currentDecoder.decodeKey(key))] = read();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
while ((key = read()) != STOP_CODE) {
|
|
315
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
316
|
+
object[safeKey(key)] = read();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
303
319
|
return object
|
|
304
320
|
} else {
|
|
305
321
|
if (restoreMapsAsObject) {
|
|
@@ -307,8 +323,24 @@
|
|
|
307
323
|
restoreMapsAsObject = false;
|
|
308
324
|
}
|
|
309
325
|
let map = new Map();
|
|
310
|
-
if (currentDecoder.keyMap)
|
|
311
|
-
|
|
326
|
+
if (currentDecoder.keyMap) {
|
|
327
|
+
let i = 0;
|
|
328
|
+
while((key = read()) != STOP_CODE) {
|
|
329
|
+
if (i++ >= maxMapSize) {
|
|
330
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
331
|
+
}
|
|
332
|
+
map.set(currentDecoder.decodeKey(key), read());
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
let i = 0;
|
|
337
|
+
while ((key = read()) != STOP_CODE) {
|
|
338
|
+
if (i++ >= maxMapSize) {
|
|
339
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
340
|
+
}
|
|
341
|
+
map.set(key, read());
|
|
342
|
+
}
|
|
343
|
+
}
|
|
312
344
|
return map
|
|
313
345
|
}
|
|
314
346
|
case 7:
|
|
@@ -339,12 +371,14 @@
|
|
|
339
371
|
}
|
|
340
372
|
return readFixedString(token)
|
|
341
373
|
case 4: // array
|
|
374
|
+
if (token >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
342
375
|
let array = new Array(token);
|
|
343
376
|
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
344
377
|
//else
|
|
345
378
|
for (let i = 0; i < token; i++) array[i] = read();
|
|
346
379
|
return array
|
|
347
380
|
case 5: // map
|
|
381
|
+
if (token >= maxMapSize) throw new Error(`Map size exceeds ${maxArraySize}`)
|
|
348
382
|
if (currentDecoder.mapsAsObjects) {
|
|
349
383
|
let object = {};
|
|
350
384
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[safeKey(currentDecoder.decodeKey(read()))] = read();
|
|
@@ -446,6 +480,7 @@
|
|
|
446
480
|
}
|
|
447
481
|
const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
|
|
448
482
|
function createStructureReader(structure) {
|
|
483
|
+
if (!structure) throw new Error('Structure is required in record definition');
|
|
449
484
|
function readObject() {
|
|
450
485
|
// get the array size from the header
|
|
451
486
|
let length = src[position$1++];
|
|
@@ -804,7 +839,7 @@
|
|
|
804
839
|
// bigint extension
|
|
805
840
|
let value = BigInt(0);
|
|
806
841
|
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
807
|
-
value = BigInt(buffer[i]) + value << BigInt(8);
|
|
842
|
+
value = BigInt(buffer[i]) + (value << BigInt(8));
|
|
808
843
|
}
|
|
809
844
|
return value
|
|
810
845
|
};
|
|
@@ -1198,8 +1233,8 @@
|
|
|
1198
1233
|
let structures;
|
|
1199
1234
|
let referenceMap;
|
|
1200
1235
|
options = options || {};
|
|
1201
|
-
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position
|
|
1202
|
-
return target.utf8Write(string, position,
|
|
1236
|
+
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
1237
|
+
return target.utf8Write(string, position, target.byteLength - position)
|
|
1203
1238
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
1204
1239
|
function(string, position) {
|
|
1205
1240
|
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
@@ -1580,7 +1615,7 @@
|
|
|
1580
1615
|
targetView.setUint32(position, value);
|
|
1581
1616
|
position += 4;
|
|
1582
1617
|
}
|
|
1583
|
-
} else if (!this.alwaysUseFloat && value >> 0 === value) { // negative integer
|
|
1618
|
+
} else if (!this.alwaysUseFloat && value >> 0 === value) { // negative integer, 31-bit or less
|
|
1584
1619
|
if (value >= -0x18) {
|
|
1585
1620
|
target[position++] = 0x1f - value;
|
|
1586
1621
|
} else if (value >= -0x100) {
|
|
@@ -1595,6 +1630,11 @@
|
|
|
1595
1630
|
targetView.setUint32(position, ~value);
|
|
1596
1631
|
position += 4;
|
|
1597
1632
|
}
|
|
1633
|
+
} else if (!this.alwaysUseFloat && value < 0 && value >= -0x100000000 && Math.floor(value) === value) {
|
|
1634
|
+
// negative integer, 32-bit or less
|
|
1635
|
+
target[position++] = 0x3a;
|
|
1636
|
+
targetView.setUint32(position, -1 - value);
|
|
1637
|
+
position += 4;
|
|
1598
1638
|
} else {
|
|
1599
1639
|
let useFloat32;
|
|
1600
1640
|
if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
|
|
@@ -1636,6 +1676,9 @@
|
|
|
1636
1676
|
}
|
|
1637
1677
|
let constructor = value.constructor;
|
|
1638
1678
|
if (constructor === Object) {
|
|
1679
|
+
if (this.skipFunction === true) {
|
|
1680
|
+
value = Object.fromEntries([...Object.keys(value).filter(x => typeof value[x] !== "function").map(x => [x, value[x]])]);
|
|
1681
|
+
}
|
|
1639
1682
|
writeObject(value);
|
|
1640
1683
|
} else if (constructor === Array) {
|
|
1641
1684
|
length = value.length;
|
|
@@ -1752,7 +1795,19 @@
|
|
|
1752
1795
|
target[position++] = 0xfb;
|
|
1753
1796
|
targetView.setFloat64(position, Number(value));
|
|
1754
1797
|
} else {
|
|
1755
|
-
|
|
1798
|
+
if (value >= BigInt(0))
|
|
1799
|
+
target[position++] = 0xc2; // tag 2
|
|
1800
|
+
else {
|
|
1801
|
+
target[position++] = 0xc3; // tag 2
|
|
1802
|
+
value = BigInt(-1) - value;
|
|
1803
|
+
}
|
|
1804
|
+
let bytes = [];
|
|
1805
|
+
while (value) {
|
|
1806
|
+
bytes.push(Number(value & BigInt(0xff)));
|
|
1807
|
+
value >>= BigInt(8);
|
|
1808
|
+
}
|
|
1809
|
+
writeBuffer(new Uint8Array(bytes.reverse()), makeRoom);
|
|
1810
|
+
return;
|
|
1756
1811
|
}
|
|
1757
1812
|
}
|
|
1758
1813
|
position += 8;
|
|
@@ -1799,7 +1854,7 @@
|
|
|
1799
1854
|
let objectOffset = position - start;
|
|
1800
1855
|
position += 2;
|
|
1801
1856
|
let size = 0;
|
|
1802
|
-
if (encoder.keyMap) {
|
|
1857
|
+
if (encoder.keyMap) {
|
|
1803
1858
|
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1804
1859
|
encode(encoder.encodeKey(key));
|
|
1805
1860
|
encode(object[key]);
|
|
@@ -1971,7 +2026,7 @@
|
|
|
1971
2026
|
yield* tryEncode(value, iterateProperties, 'element');
|
|
1972
2027
|
} else encode(value);
|
|
1973
2028
|
}
|
|
1974
|
-
} else if (object[Symbol.iterator]) {
|
|
2029
|
+
} else if (object[Symbol.iterator] && !object.buffer) { // iterator, but exclude typed arrays
|
|
1975
2030
|
target[position++] = 0x9f; // start indefinite array
|
|
1976
2031
|
for (let value of object) {
|
|
1977
2032
|
if (value && (typeof value === 'object' || position - start > chunkThreshold)) {
|
|
@@ -2548,6 +2603,10 @@
|
|
|
2548
2603
|
assert.equal(deserialized, data);
|
|
2549
2604
|
});
|
|
2550
2605
|
|
|
2606
|
+
test('string overflow', function() {
|
|
2607
|
+
assert.throws(() => decode$1(Buffer.from('7a10000000', 'hex')));
|
|
2608
|
+
});
|
|
2609
|
+
|
|
2551
2610
|
test('encode/decode sample data', function(){
|
|
2552
2611
|
var data = sampleData;
|
|
2553
2612
|
var serialized = encode$1(data);
|
|
@@ -3035,7 +3094,12 @@
|
|
|
3035
3094
|
var deserialized = decode(serialized);
|
|
3036
3095
|
assert.deepEqual(deserialized, data);
|
|
3037
3096
|
});
|
|
3038
|
-
|
|
3097
|
+
test('numbers are compact', function(){
|
|
3098
|
+
assert.equal(encode(-256).length, 2);
|
|
3099
|
+
let encoding = encode(-4294967296);
|
|
3100
|
+
assert.equal(encoding.length, 5);
|
|
3101
|
+
assert.equal(decode(encoding), -4294967296);
|
|
3102
|
+
});
|
|
3039
3103
|
test('encode ArrayBuffer', function() {
|
|
3040
3104
|
let ua = new Uint8Array([3, 4, 5]);
|
|
3041
3105
|
let encoded = encode(ua.buffer);
|
|
@@ -3060,23 +3124,27 @@
|
|
|
3060
3124
|
var data = {
|
|
3061
3125
|
bigintSmall: 352n,
|
|
3062
3126
|
bigintSmallNegative: -333335252n,
|
|
3063
|
-
bigintBig: 2n**64n - 1n, // biggest possible
|
|
3127
|
+
bigintBig: 2n**64n - 1n, // biggest 64-bit possible
|
|
3064
3128
|
bigintBigNegative: -(2n**63n), // largest negative
|
|
3065
3129
|
mixedWithNormal: 44,
|
|
3066
3130
|
};
|
|
3067
3131
|
var serialized = encode(data);
|
|
3068
3132
|
var deserialized = decode(serialized);
|
|
3069
3133
|
assert.deepEqual(deserialized, data);
|
|
3070
|
-
var
|
|
3071
|
-
|
|
3134
|
+
var evenBiggerInt = {
|
|
3135
|
+
big: 2n**66n,
|
|
3136
|
+
bigger: 53285732853728573289573289573289573289583725892358732859532n,
|
|
3137
|
+
negBig: -93025879203578903275903285903285903289502n,
|
|
3072
3138
|
};
|
|
3073
|
-
|
|
3139
|
+
var serialized = encode(evenBiggerInt);
|
|
3140
|
+
var deserialized = decode(serialized);
|
|
3141
|
+
assert.deepEqual(deserialized, evenBiggerInt);
|
|
3074
3142
|
let encoder = new Encoder({
|
|
3075
3143
|
largeBigIntToFloat: true
|
|
3076
3144
|
});
|
|
3077
|
-
serialized = encoder.encode(
|
|
3145
|
+
serialized = encoder.encode(evenBiggerInt);
|
|
3078
3146
|
deserialized = decode(serialized);
|
|
3079
|
-
assert.isTrue(deserialized.
|
|
3147
|
+
assert.isTrue(deserialized.bigger > 2n**65n);
|
|
3080
3148
|
});
|
|
3081
3149
|
|
|
3082
3150
|
test('buffers', function() {
|
|
@@ -3130,6 +3198,20 @@
|
|
|
3130
3198
|
decodeMultiple(new Uint8Array([1, 2, 3, 4]), value => values.push(value));
|
|
3131
3199
|
assert.deepEqual(values, [1, 2, 3, 4]);
|
|
3132
3200
|
});
|
|
3201
|
+
test('skipFunction', () => {
|
|
3202
|
+
var data = {
|
|
3203
|
+
a: 325283295382932843n,
|
|
3204
|
+
f: () => {},
|
|
3205
|
+
};
|
|
3206
|
+
let encoder = new Encoder({
|
|
3207
|
+
int64AsNumber: true,
|
|
3208
|
+
skipFunction: true,
|
|
3209
|
+
});
|
|
3210
|
+
var serialized = encoder.encode(data);
|
|
3211
|
+
var deserialized = encoder.decode(serialized);
|
|
3212
|
+
assert.deepEqual(deserialized.a, 325283295382932843);
|
|
3213
|
+
assert.equal(Object.hasOwn(deserialized, "f"), false);
|
|
3214
|
+
});
|
|
3133
3215
|
test('bad input', function() {
|
|
3134
3216
|
let badInput = Buffer.from('7b2273657269616c6e6f223a2265343a30222c226970223a223139322e3136382e312e3335222c226b6579223a226770735f736563726574227d', 'hex');
|
|
3135
3217
|
assert.throws(function(){ decode(badInput); }); // should throw, not crash
|