cbor-x 1.5.8 → 1.6.0
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 +12 -0
- package/decode.d.ts +1 -1
- package/decode.js +67 -9
- package/dist/decode-no-eval.cjs +65 -9
- package/dist/decode-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.cjs +92 -25
- 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 +92 -25
- 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 +93 -25
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +149 -42
- package/dist/test.js.map +1 -1
- package/encode.js +28 -16
- package/index.d.ts +6 -1
- package/index.js +1 -1
- package/node-index.js +1 -1
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
const BUNDLED_STRINGS_ID = 0xdff9;
|
|
18
18
|
const PACKED_REFERENCE_TAG_ID = 6;
|
|
19
19
|
const STOP_CODE = {};
|
|
20
|
+
let maxArraySize = 112810000; // This is the maximum array size in V8. We would potentially detect and set it higher
|
|
21
|
+
// for JSC, but this is pretty large and should be sufficient for most use cases
|
|
22
|
+
let maxMapSize = 16810000; // JavaScript has a fixed maximum map size of about 16710000, but JS itself enforces this,
|
|
20
23
|
let currentDecoder = {};
|
|
21
24
|
let currentStructures;
|
|
22
25
|
let srcString;
|
|
@@ -289,6 +292,7 @@
|
|
|
289
292
|
let array = [];
|
|
290
293
|
let value, i = 0;
|
|
291
294
|
while ((value = read()) != STOP_CODE) {
|
|
295
|
+
if (i >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
292
296
|
array[i++] = value;
|
|
293
297
|
}
|
|
294
298
|
return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
|
|
@@ -296,8 +300,19 @@
|
|
|
296
300
|
let key;
|
|
297
301
|
if (currentDecoder.mapsAsObjects) {
|
|
298
302
|
let object = {};
|
|
299
|
-
|
|
300
|
-
|
|
303
|
+
let i = 0;
|
|
304
|
+
if (currentDecoder.keyMap) {
|
|
305
|
+
while((key = read()) != STOP_CODE) {
|
|
306
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
307
|
+
object[safeKey(currentDecoder.decodeKey(key))] = read();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
while ((key = read()) != STOP_CODE) {
|
|
312
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
313
|
+
object[safeKey(key)] = read();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
301
316
|
return object
|
|
302
317
|
} else {
|
|
303
318
|
if (restoreMapsAsObject) {
|
|
@@ -305,8 +320,24 @@
|
|
|
305
320
|
restoreMapsAsObject = false;
|
|
306
321
|
}
|
|
307
322
|
let map = new Map();
|
|
308
|
-
if (currentDecoder.keyMap)
|
|
309
|
-
|
|
323
|
+
if (currentDecoder.keyMap) {
|
|
324
|
+
let i = 0;
|
|
325
|
+
while((key = read()) != STOP_CODE) {
|
|
326
|
+
if (i++ >= maxMapSize) {
|
|
327
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
328
|
+
}
|
|
329
|
+
map.set(currentDecoder.decodeKey(key), read());
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
let i = 0;
|
|
334
|
+
while ((key = read()) != STOP_CODE) {
|
|
335
|
+
if (i++ >= maxMapSize) {
|
|
336
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
337
|
+
}
|
|
338
|
+
map.set(key, read());
|
|
339
|
+
}
|
|
340
|
+
}
|
|
310
341
|
return map
|
|
311
342
|
}
|
|
312
343
|
case 7:
|
|
@@ -337,12 +368,14 @@
|
|
|
337
368
|
}
|
|
338
369
|
return readFixedString(token)
|
|
339
370
|
case 4: // array
|
|
371
|
+
if (token >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
340
372
|
let array = new Array(token);
|
|
341
373
|
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
342
374
|
//else
|
|
343
375
|
for (let i = 0; i < token; i++) array[i] = read();
|
|
344
376
|
return array
|
|
345
377
|
case 5: // map
|
|
378
|
+
if (token >= maxMapSize) throw new Error(`Map size exceeds ${maxArraySize}`)
|
|
346
379
|
if (currentDecoder.mapsAsObjects) {
|
|
347
380
|
let object = {};
|
|
348
381
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[safeKey(currentDecoder.decodeKey(read()))] = read();
|
|
@@ -444,6 +477,7 @@
|
|
|
444
477
|
}
|
|
445
478
|
const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
|
|
446
479
|
function createStructureReader(structure) {
|
|
480
|
+
if (!structure) throw new Error('Structure is required in record definition');
|
|
447
481
|
function readObject() {
|
|
448
482
|
// get the array size from the header
|
|
449
483
|
let length = src[position$1++];
|
|
@@ -499,7 +533,8 @@
|
|
|
499
533
|
function safeKey(key) {
|
|
500
534
|
// protect against prototype pollution
|
|
501
535
|
if (typeof key === 'string') return key === '__proto__' ? '__proto_' : key
|
|
502
|
-
if (typeof key
|
|
536
|
+
if (typeof key === 'number' || typeof key === 'boolean' || typeof key === 'bigint') return key.toString();
|
|
537
|
+
if (key == null) return key + '';
|
|
503
538
|
// protect against expensive (DoS) string conversions
|
|
504
539
|
throw new Error('Invalid property name type ' + typeof key);
|
|
505
540
|
}
|
|
@@ -769,7 +804,7 @@
|
|
|
769
804
|
// bigint extension
|
|
770
805
|
let value = BigInt(0);
|
|
771
806
|
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
772
|
-
value = BigInt(buffer[i]) + value << BigInt(8);
|
|
807
|
+
value = BigInt(buffer[i]) + (value << BigInt(8));
|
|
773
808
|
}
|
|
774
809
|
return value
|
|
775
810
|
};
|
|
@@ -884,6 +919,7 @@
|
|
|
884
919
|
referenceMap.id = 0;
|
|
885
920
|
}
|
|
886
921
|
let id = referenceMap.id++;
|
|
922
|
+
let startingPosition = position$1;
|
|
887
923
|
let token = src[position$1];
|
|
888
924
|
let target;
|
|
889
925
|
// TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
|
|
@@ -896,8 +932,20 @@
|
|
|
896
932
|
let refEntry = { target }; // a placeholder object
|
|
897
933
|
referenceMap.set(id, refEntry);
|
|
898
934
|
let targetProperties = read(); // read the next value as the target object to id
|
|
899
|
-
if (refEntry.used) // there is a cycle, so we have to assign properties to original target
|
|
935
|
+
if (refEntry.used) {// there is a cycle, so we have to assign properties to original target
|
|
936
|
+
if (Object.getPrototypeOf(target) !== Object.getPrototypeOf(targetProperties)) {
|
|
937
|
+
// this means that the returned target does not match the targetProperties, so we need rerun the read to
|
|
938
|
+
// have the correctly create instance be assigned as a reference, then we do the copy the properties back to the
|
|
939
|
+
// target
|
|
940
|
+
// reset the position so that the read can be repeated
|
|
941
|
+
position$1 = startingPosition;
|
|
942
|
+
// the returned instance is our new target for references
|
|
943
|
+
target = targetProperties;
|
|
944
|
+
referenceMap.set(id, { target });
|
|
945
|
+
targetProperties = read();
|
|
946
|
+
}
|
|
900
947
|
return Object.assign(target, targetProperties)
|
|
948
|
+
}
|
|
901
949
|
refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
|
|
902
950
|
return targetProperties // no cycle, can just use the returned read object
|
|
903
951
|
};
|
|
@@ -979,7 +1027,7 @@
|
|
|
979
1027
|
for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
|
|
980
1028
|
if (!littleEndian && bytesPerElement == 1)
|
|
981
1029
|
continue
|
|
982
|
-
let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
|
|
1030
|
+
let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : bytesPerElement == 8 ? 3 : 0;
|
|
983
1031
|
currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine$1) ? (buffer) => {
|
|
984
1032
|
if (!TypedArray)
|
|
985
1033
|
throw new Error('Could not find typed array for code ' + tag)
|
|
@@ -989,7 +1037,7 @@
|
|
|
989
1037
|
bytesPerElement === 2 && !(buffer.byteOffset & 1) ||
|
|
990
1038
|
bytesPerElement === 4 && !(buffer.byteOffset & 3) ||
|
|
991
1039
|
bytesPerElement === 8 && !(buffer.byteOffset & 7))
|
|
992
|
-
return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
1040
|
+
return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength >> sizeShift);
|
|
993
1041
|
}
|
|
994
1042
|
// we have to slice/copy here to get a new ArrayBuffer, if we are not word/byte aligned
|
|
995
1043
|
return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
|
|
@@ -1102,6 +1150,12 @@
|
|
|
1102
1150
|
currentExtensions[extension.tag] = extension.decode;
|
|
1103
1151
|
}
|
|
1104
1152
|
|
|
1153
|
+
function setSizeLimits(limits) {
|
|
1154
|
+
if (limits.maxMapSize) maxMapSize = limits.maxMapSize;
|
|
1155
|
+
if (limits.maxArraySize) maxArraySize = limits.maxArraySize;
|
|
1156
|
+
if (limits.maxObjectSize) limits.maxObjectSize;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1105
1159
|
const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
1106
1160
|
for (let i = 0; i < 256; i++) {
|
|
1107
1161
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
|
|
@@ -1589,7 +1643,7 @@
|
|
|
1589
1643
|
}
|
|
1590
1644
|
let constructor = value.constructor;
|
|
1591
1645
|
if (constructor === Object) {
|
|
1592
|
-
writeObject(value
|
|
1646
|
+
writeObject(value);
|
|
1593
1647
|
} else if (constructor === Array) {
|
|
1594
1648
|
length = value.length;
|
|
1595
1649
|
if (length < 0x18) {
|
|
@@ -1684,8 +1738,8 @@
|
|
|
1684
1738
|
return encode(json)
|
|
1685
1739
|
}
|
|
1686
1740
|
|
|
1687
|
-
// no extension found, write as object
|
|
1688
|
-
writeObject(value
|
|
1741
|
+
// no extension found, write as a plain object
|
|
1742
|
+
writeObject(value);
|
|
1689
1743
|
}
|
|
1690
1744
|
}
|
|
1691
1745
|
} else if (type === 'boolean') {
|
|
@@ -1705,7 +1759,19 @@
|
|
|
1705
1759
|
target[position++] = 0xfb;
|
|
1706
1760
|
targetView.setFloat64(position, Number(value));
|
|
1707
1761
|
} else {
|
|
1708
|
-
|
|
1762
|
+
if (value >= BigInt(0))
|
|
1763
|
+
target[position++] = 0xc2; // tag 2
|
|
1764
|
+
else {
|
|
1765
|
+
target[position++] = 0xc3; // tag 2
|
|
1766
|
+
value = BigInt(-1) - value;
|
|
1767
|
+
}
|
|
1768
|
+
let bytes = [];
|
|
1769
|
+
while (value) {
|
|
1770
|
+
bytes.push(Number(value & BigInt(0xff)));
|
|
1771
|
+
value >>= BigInt(8);
|
|
1772
|
+
}
|
|
1773
|
+
writeBuffer(new Uint8Array(bytes.reverse()), makeRoom);
|
|
1774
|
+
return;
|
|
1709
1775
|
}
|
|
1710
1776
|
}
|
|
1711
1777
|
position += 8;
|
|
@@ -1747,19 +1813,19 @@
|
|
|
1747
1813
|
}
|
|
1748
1814
|
}
|
|
1749
1815
|
} :
|
|
1750
|
-
(object
|
|
1816
|
+
(object) => {
|
|
1751
1817
|
target[position++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
|
|
1752
1818
|
let objectOffset = position - start;
|
|
1753
1819
|
position += 2;
|
|
1754
1820
|
let size = 0;
|
|
1755
|
-
if (encoder.keyMap) {
|
|
1756
|
-
for (let key in object) if (
|
|
1821
|
+
if (encoder.keyMap) {
|
|
1822
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1757
1823
|
encode(encoder.encodeKey(key));
|
|
1758
1824
|
encode(object[key]);
|
|
1759
1825
|
size++;
|
|
1760
1826
|
}
|
|
1761
1827
|
} else {
|
|
1762
|
-
for (let key in object) if (
|
|
1828
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1763
1829
|
encode(key);
|
|
1764
1830
|
encode(object[key]);
|
|
1765
1831
|
size++;
|
|
@@ -1768,7 +1834,7 @@
|
|
|
1768
1834
|
target[objectOffset++ + start] = size >> 8;
|
|
1769
1835
|
target[objectOffset + start] = size & 0xff;
|
|
1770
1836
|
} :
|
|
1771
|
-
(object,
|
|
1837
|
+
(object, skipValues) => {
|
|
1772
1838
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1773
1839
|
let newTransitions = 0;
|
|
1774
1840
|
let length = 0;
|
|
@@ -1787,7 +1853,7 @@
|
|
|
1787
1853
|
transition = nextTransition;
|
|
1788
1854
|
}
|
|
1789
1855
|
} else {
|
|
1790
|
-
for (let key in object) if (
|
|
1856
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1791
1857
|
nextTransition = transition[key];
|
|
1792
1858
|
if (!nextTransition) {
|
|
1793
1859
|
if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
|
|
@@ -1847,9 +1913,9 @@
|
|
|
1847
1913
|
writeArrayHeader(length + 2);
|
|
1848
1914
|
encode(0xe000 + recordId);
|
|
1849
1915
|
encode(keys);
|
|
1850
|
-
if (
|
|
1916
|
+
if (skipValues) return; // special exit for iterator
|
|
1851
1917
|
for (let key in object)
|
|
1852
|
-
if (
|
|
1918
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
|
|
1853
1919
|
encode(object[key]);
|
|
1854
1920
|
return
|
|
1855
1921
|
}
|
|
@@ -1859,9 +1925,9 @@
|
|
|
1859
1925
|
} else {
|
|
1860
1926
|
writeArrayHeader(length);
|
|
1861
1927
|
}
|
|
1862
|
-
if (
|
|
1928
|
+
if (skipValues) return; // special exit for iterator
|
|
1863
1929
|
for (let key in object)
|
|
1864
|
-
if (
|
|
1930
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
|
|
1865
1931
|
encode(object[key]);
|
|
1866
1932
|
};
|
|
1867
1933
|
const makeRoom = (end) => {
|
|
@@ -1899,7 +1965,7 @@
|
|
|
1899
1965
|
if (constructor === Object) {
|
|
1900
1966
|
let useRecords = encoder.useRecords !== false;
|
|
1901
1967
|
if (useRecords)
|
|
1902
|
-
writeObject(object,
|
|
1968
|
+
writeObject(object, true); // write the record identifier
|
|
1903
1969
|
else
|
|
1904
1970
|
writeEntityLength(Object.keys(object).length, 0xa0);
|
|
1905
1971
|
for (let key in object) {
|
|
@@ -1924,7 +1990,7 @@
|
|
|
1924
1990
|
yield* tryEncode(value, iterateProperties, 'element');
|
|
1925
1991
|
} else encode(value);
|
|
1926
1992
|
}
|
|
1927
|
-
} else if (object[Symbol.iterator]) {
|
|
1993
|
+
} else if (object[Symbol.iterator] && !object.buffer) { // iterator, but exclude typed arrays
|
|
1928
1994
|
target[position++] = 0x9f; // start indefinite array
|
|
1929
1995
|
for (let value of object) {
|
|
1930
1996
|
if (value && (typeof value === 'object' || position - start > chunkThreshold)) {
|
|
@@ -2436,6 +2502,7 @@
|
|
|
2436
2502
|
exports.encodeIter = encodeIter;
|
|
2437
2503
|
exports.isNativeAccelerationEnabled = isNativeAccelerationEnabled;
|
|
2438
2504
|
exports.roundFloat32 = roundFloat32;
|
|
2505
|
+
exports.setSizeLimits = setSizeLimits;
|
|
2439
2506
|
|
|
2440
2507
|
}));
|
|
2441
2508
|
//# sourceMappingURL=index.js.map
|