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/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 = {};
|
|
@@ -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++];
|
|
@@ -501,7 +536,8 @@
|
|
|
501
536
|
function safeKey(key) {
|
|
502
537
|
// protect against prototype pollution
|
|
503
538
|
if (typeof key === 'string') return key === '__proto__' ? '__proto_' : key
|
|
504
|
-
if (typeof key
|
|
539
|
+
if (typeof key === 'number' || typeof key === 'boolean' || typeof key === 'bigint') return key.toString();
|
|
540
|
+
if (key == null) return key + '';
|
|
505
541
|
// protect against expensive (DoS) string conversions
|
|
506
542
|
throw new Error('Invalid property name type ' + typeof key);
|
|
507
543
|
}
|
|
@@ -803,7 +839,7 @@
|
|
|
803
839
|
// bigint extension
|
|
804
840
|
let value = BigInt(0);
|
|
805
841
|
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
806
|
-
value = BigInt(buffer[i]) + value << BigInt(8);
|
|
842
|
+
value = BigInt(buffer[i]) + (value << BigInt(8));
|
|
807
843
|
}
|
|
808
844
|
return value
|
|
809
845
|
};
|
|
@@ -918,6 +954,7 @@
|
|
|
918
954
|
referenceMap.id = 0;
|
|
919
955
|
}
|
|
920
956
|
let id = referenceMap.id++;
|
|
957
|
+
let startingPosition = position$1;
|
|
921
958
|
let token = src[position$1];
|
|
922
959
|
let target;
|
|
923
960
|
// TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
|
|
@@ -930,8 +967,20 @@
|
|
|
930
967
|
let refEntry = { target }; // a placeholder object
|
|
931
968
|
referenceMap.set(id, refEntry);
|
|
932
969
|
let targetProperties = read(); // read the next value as the target object to id
|
|
933
|
-
if (refEntry.used) // there is a cycle, so we have to assign properties to original target
|
|
970
|
+
if (refEntry.used) {// there is a cycle, so we have to assign properties to original target
|
|
971
|
+
if (Object.getPrototypeOf(target) !== Object.getPrototypeOf(targetProperties)) {
|
|
972
|
+
// this means that the returned target does not match the targetProperties, so we need rerun the read to
|
|
973
|
+
// have the correctly create instance be assigned as a reference, then we do the copy the properties back to the
|
|
974
|
+
// target
|
|
975
|
+
// reset the position so that the read can be repeated
|
|
976
|
+
position$1 = startingPosition;
|
|
977
|
+
// the returned instance is our new target for references
|
|
978
|
+
target = targetProperties;
|
|
979
|
+
referenceMap.set(id, { target });
|
|
980
|
+
targetProperties = read();
|
|
981
|
+
}
|
|
934
982
|
return Object.assign(target, targetProperties)
|
|
983
|
+
}
|
|
935
984
|
refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
|
|
936
985
|
return targetProperties // no cycle, can just use the returned read object
|
|
937
986
|
};
|
|
@@ -1013,7 +1062,7 @@
|
|
|
1013
1062
|
for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
|
|
1014
1063
|
if (!littleEndian && bytesPerElement == 1)
|
|
1015
1064
|
continue
|
|
1016
|
-
let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
|
|
1065
|
+
let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : bytesPerElement == 8 ? 3 : 0;
|
|
1017
1066
|
currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine$1) ? (buffer) => {
|
|
1018
1067
|
if (!TypedArray)
|
|
1019
1068
|
throw new Error('Could not find typed array for code ' + tag)
|
|
@@ -1023,7 +1072,7 @@
|
|
|
1023
1072
|
bytesPerElement === 2 && !(buffer.byteOffset & 1) ||
|
|
1024
1073
|
bytesPerElement === 4 && !(buffer.byteOffset & 3) ||
|
|
1025
1074
|
bytesPerElement === 8 && !(buffer.byteOffset & 7))
|
|
1026
|
-
return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
1075
|
+
return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength >> sizeShift);
|
|
1027
1076
|
}
|
|
1028
1077
|
// we have to slice/copy here to get a new ArrayBuffer, if we are not word/byte aligned
|
|
1029
1078
|
return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
|
|
@@ -1622,7 +1671,7 @@
|
|
|
1622
1671
|
}
|
|
1623
1672
|
let constructor = value.constructor;
|
|
1624
1673
|
if (constructor === Object) {
|
|
1625
|
-
writeObject(value
|
|
1674
|
+
writeObject(value);
|
|
1626
1675
|
} else if (constructor === Array) {
|
|
1627
1676
|
length = value.length;
|
|
1628
1677
|
if (length < 0x18) {
|
|
@@ -1717,8 +1766,8 @@
|
|
|
1717
1766
|
return encode(json)
|
|
1718
1767
|
}
|
|
1719
1768
|
|
|
1720
|
-
// no extension found, write as object
|
|
1721
|
-
writeObject(value
|
|
1769
|
+
// no extension found, write as a plain object
|
|
1770
|
+
writeObject(value);
|
|
1722
1771
|
}
|
|
1723
1772
|
}
|
|
1724
1773
|
} else if (type === 'boolean') {
|
|
@@ -1738,7 +1787,19 @@
|
|
|
1738
1787
|
target[position++] = 0xfb;
|
|
1739
1788
|
targetView.setFloat64(position, Number(value));
|
|
1740
1789
|
} else {
|
|
1741
|
-
|
|
1790
|
+
if (value >= BigInt(0))
|
|
1791
|
+
target[position++] = 0xc2; // tag 2
|
|
1792
|
+
else {
|
|
1793
|
+
target[position++] = 0xc3; // tag 2
|
|
1794
|
+
value = BigInt(-1) - value;
|
|
1795
|
+
}
|
|
1796
|
+
let bytes = [];
|
|
1797
|
+
while (value) {
|
|
1798
|
+
bytes.push(Number(value & BigInt(0xff)));
|
|
1799
|
+
value >>= BigInt(8);
|
|
1800
|
+
}
|
|
1801
|
+
writeBuffer(new Uint8Array(bytes.reverse()), makeRoom);
|
|
1802
|
+
return;
|
|
1742
1803
|
}
|
|
1743
1804
|
}
|
|
1744
1805
|
position += 8;
|
|
@@ -1780,19 +1841,19 @@
|
|
|
1780
1841
|
}
|
|
1781
1842
|
}
|
|
1782
1843
|
} :
|
|
1783
|
-
(object
|
|
1844
|
+
(object) => {
|
|
1784
1845
|
target[position++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
|
|
1785
1846
|
let objectOffset = position - start;
|
|
1786
1847
|
position += 2;
|
|
1787
1848
|
let size = 0;
|
|
1788
|
-
if (encoder.keyMap) {
|
|
1789
|
-
for (let key in object) if (
|
|
1849
|
+
if (encoder.keyMap) {
|
|
1850
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1790
1851
|
encode(encoder.encodeKey(key));
|
|
1791
1852
|
encode(object[key]);
|
|
1792
1853
|
size++;
|
|
1793
1854
|
}
|
|
1794
1855
|
} else {
|
|
1795
|
-
for (let key in object) if (
|
|
1856
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1796
1857
|
encode(key);
|
|
1797
1858
|
encode(object[key]);
|
|
1798
1859
|
size++;
|
|
@@ -1801,7 +1862,7 @@
|
|
|
1801
1862
|
target[objectOffset++ + start] = size >> 8;
|
|
1802
1863
|
target[objectOffset + start] = size & 0xff;
|
|
1803
1864
|
} :
|
|
1804
|
-
(object,
|
|
1865
|
+
(object, skipValues) => {
|
|
1805
1866
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1806
1867
|
let newTransitions = 0;
|
|
1807
1868
|
let length = 0;
|
|
@@ -1820,7 +1881,7 @@
|
|
|
1820
1881
|
transition = nextTransition;
|
|
1821
1882
|
}
|
|
1822
1883
|
} else {
|
|
1823
|
-
for (let key in object) if (
|
|
1884
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1824
1885
|
nextTransition = transition[key];
|
|
1825
1886
|
if (!nextTransition) {
|
|
1826
1887
|
if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
|
|
@@ -1880,9 +1941,9 @@
|
|
|
1880
1941
|
writeArrayHeader(length + 2);
|
|
1881
1942
|
encode(0xe000 + recordId);
|
|
1882
1943
|
encode(keys);
|
|
1883
|
-
if (
|
|
1944
|
+
if (skipValues) return; // special exit for iterator
|
|
1884
1945
|
for (let key in object)
|
|
1885
|
-
if (
|
|
1946
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
|
|
1886
1947
|
encode(object[key]);
|
|
1887
1948
|
return
|
|
1888
1949
|
}
|
|
@@ -1892,9 +1953,9 @@
|
|
|
1892
1953
|
} else {
|
|
1893
1954
|
writeArrayHeader(length);
|
|
1894
1955
|
}
|
|
1895
|
-
if (
|
|
1956
|
+
if (skipValues) return; // special exit for iterator
|
|
1896
1957
|
for (let key in object)
|
|
1897
|
-
if (
|
|
1958
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
|
|
1898
1959
|
encode(object[key]);
|
|
1899
1960
|
};
|
|
1900
1961
|
const makeRoom = (end) => {
|
|
@@ -1932,7 +1993,7 @@
|
|
|
1932
1993
|
if (constructor === Object) {
|
|
1933
1994
|
let useRecords = encoder.useRecords !== false;
|
|
1934
1995
|
if (useRecords)
|
|
1935
|
-
writeObject(object,
|
|
1996
|
+
writeObject(object, true); // write the record identifier
|
|
1936
1997
|
else
|
|
1937
1998
|
writeEntityLength(Object.keys(object).length, 0xa0);
|
|
1938
1999
|
for (let key in object) {
|
|
@@ -1957,7 +2018,7 @@
|
|
|
1957
2018
|
yield* tryEncode(value, iterateProperties, 'element');
|
|
1958
2019
|
} else encode(value);
|
|
1959
2020
|
}
|
|
1960
|
-
} else if (object[Symbol.iterator]) {
|
|
2021
|
+
} else if (object[Symbol.iterator] && !object.buffer) { // iterator, but exclude typed arrays
|
|
1961
2022
|
target[position++] = 0x9f; // start indefinite array
|
|
1962
2023
|
for (let value of object) {
|
|
1963
2024
|
if (value && (typeof value === 'object' || position - start > chunkThreshold)) {
|
|
@@ -2649,22 +2710,17 @@
|
|
|
2649
2710
|
assert.deepEqual(deserialized1, data1);
|
|
2650
2711
|
assert.deepEqual(deserialized2, data2);
|
|
2651
2712
|
});
|
|
2652
|
-
test('extended class encode/decode', function(){
|
|
2713
|
+
test('extended class encode/decode', function() {
|
|
2653
2714
|
function Extended() {
|
|
2654
2715
|
|
|
2655
2716
|
}
|
|
2717
|
+
|
|
2656
2718
|
Extended.prototype.getDouble = function() {
|
|
2657
2719
|
return this.value * 2
|
|
2658
2720
|
};
|
|
2659
2721
|
var instance = new Extended();
|
|
2660
2722
|
instance.value = 4;
|
|
2661
2723
|
instance.string = 'decode this: ᾜ';
|
|
2662
|
-
var data = {
|
|
2663
|
-
prop1: 'has multi-byte: ᾜ',
|
|
2664
|
-
extendedInstance: instance,
|
|
2665
|
-
prop2: 'more string',
|
|
2666
|
-
num: 3,
|
|
2667
|
-
};
|
|
2668
2724
|
let encoder = new Encoder();
|
|
2669
2725
|
addExtension({
|
|
2670
2726
|
Class: Extended,
|
|
@@ -2679,10 +2735,37 @@
|
|
|
2679
2735
|
return encoder.encode([instance.value, instance.string])
|
|
2680
2736
|
}
|
|
2681
2737
|
});
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2738
|
+
});
|
|
2739
|
+
test('extended class encode/decode with self reference in structered clone', function(){
|
|
2740
|
+
function Extended() {
|
|
2741
|
+
|
|
2742
|
+
}
|
|
2743
|
+
addExtension({
|
|
2744
|
+
Class: Extended,
|
|
2745
|
+
tag: 301,
|
|
2746
|
+
decode: function(data) {
|
|
2747
|
+
let e = new Extended();
|
|
2748
|
+
e.value = data[0];
|
|
2749
|
+
e.string = data[1];
|
|
2750
|
+
return e
|
|
2751
|
+
},
|
|
2752
|
+
encode: function(instance, encode) {
|
|
2753
|
+
return encode([instance.value, instance.string])
|
|
2754
|
+
}
|
|
2755
|
+
});
|
|
2756
|
+
var instance = new Extended();
|
|
2757
|
+
instance.value = instance;
|
|
2758
|
+
instance.string = 'hi';
|
|
2759
|
+
let data = {
|
|
2760
|
+
extended: instance
|
|
2761
|
+
};
|
|
2762
|
+
let encoder = new Encoder({
|
|
2763
|
+
structuredClone: true,
|
|
2764
|
+
});
|
|
2765
|
+
let serialized = encoder.encode(data);
|
|
2766
|
+
encoder.decode(serialized);
|
|
2767
|
+
assert(data.extended.value.value === data.extended);
|
|
2768
|
+
assert(data.extended instanceof Extended);
|
|
2686
2769
|
});
|
|
2687
2770
|
|
|
2688
2771
|
test('addExtension with map', function(){
|
|
@@ -2824,6 +2907,12 @@
|
|
|
2824
2907
|
var deserialized = decode(serialized);
|
|
2825
2908
|
assert.deepEqual(deserialized, data);
|
|
2826
2909
|
});
|
|
2910
|
+
test('object with __proto__', function(){
|
|
2911
|
+
const data = { foo: 'bar', __proto__: { isAdmin: true } };
|
|
2912
|
+
var serialized = encode(data);
|
|
2913
|
+
var deserialized = decode(serialized);
|
|
2914
|
+
assert.deepEqual(deserialized, { foo: 'bar' });
|
|
2915
|
+
});
|
|
2827
2916
|
|
|
2828
2917
|
test('big buffer', function() {
|
|
2829
2918
|
var size = 100000000;
|
|
@@ -3018,23 +3107,27 @@
|
|
|
3018
3107
|
var data = {
|
|
3019
3108
|
bigintSmall: 352n,
|
|
3020
3109
|
bigintSmallNegative: -333335252n,
|
|
3021
|
-
bigintBig: 2n**64n - 1n, // biggest possible
|
|
3110
|
+
bigintBig: 2n**64n - 1n, // biggest 64-bit possible
|
|
3022
3111
|
bigintBigNegative: -(2n**63n), // largest negative
|
|
3023
3112
|
mixedWithNormal: 44,
|
|
3024
3113
|
};
|
|
3025
3114
|
var serialized = encode(data);
|
|
3026
3115
|
var deserialized = decode(serialized);
|
|
3027
3116
|
assert.deepEqual(deserialized, data);
|
|
3028
|
-
var
|
|
3029
|
-
|
|
3117
|
+
var evenBiggerInt = {
|
|
3118
|
+
big: 2n**66n,
|
|
3119
|
+
bigger: 53285732853728573289573289573289573289583725892358732859532n,
|
|
3120
|
+
negBig: -93025879203578903275903285903285903289502n,
|
|
3030
3121
|
};
|
|
3031
|
-
|
|
3122
|
+
var serialized = encode(evenBiggerInt);
|
|
3123
|
+
var deserialized = decode(serialized);
|
|
3124
|
+
assert.deepEqual(deserialized, evenBiggerInt);
|
|
3032
3125
|
let encoder = new Encoder({
|
|
3033
3126
|
largeBigIntToFloat: true
|
|
3034
3127
|
});
|
|
3035
|
-
serialized = encoder.encode(
|
|
3128
|
+
serialized = encoder.encode(evenBiggerInt);
|
|
3036
3129
|
deserialized = decode(serialized);
|
|
3037
|
-
assert.isTrue(deserialized.
|
|
3130
|
+
assert.isTrue(deserialized.bigger > 2n**65n);
|
|
3038
3131
|
});
|
|
3039
3132
|
|
|
3040
3133
|
test('buffers', function() {
|
|
@@ -3092,6 +3185,11 @@
|
|
|
3092
3185
|
let badInput = Buffer.from('7b2273657269616c6e6f223a2265343a30222c226970223a223139322e3136382e312e3335222c226b6579223a226770735f736563726574227d', 'hex');
|
|
3093
3186
|
assert.throws(function(){ decode(badInput); }); // should throw, not crash
|
|
3094
3187
|
});
|
|
3188
|
+
test('buffer key', function() {
|
|
3189
|
+
let encoder = new Encoder({ mapsAsObjects: false });
|
|
3190
|
+
let test = encoder.decode(Buffer.from('D87982A1446E616D654361626301', 'hex'));
|
|
3191
|
+
console.log(test);
|
|
3192
|
+
});
|
|
3095
3193
|
test('encode as iterator', function() {
|
|
3096
3194
|
let hasIterables = {
|
|
3097
3195
|
a: 1,
|
|
@@ -3184,6 +3282,15 @@
|
|
|
3184
3282
|
decode(Buffer.concat(result));
|
|
3185
3283
|
console.log(performance.now() - start, result.length);
|
|
3186
3284
|
});
|
|
3285
|
+
|
|
3286
|
+
test('little-endian typed array with aligned data', function() {
|
|
3287
|
+
// array[1] { uint32-little-endian-typed-array { bytes <00 00 00 00> } }
|
|
3288
|
+
let data = new Uint8Array([ 129, 216, 70, 68, 0, 0, 0, 0 ]);
|
|
3289
|
+
assert.deepEqual(decode(data), [new Uint32Array([0])]);
|
|
3290
|
+
|
|
3291
|
+
let value = {x: new Float32Array([1, 2, 3])};
|
|
3292
|
+
assert.deepEqual(decode(encode(value)), value);
|
|
3293
|
+
});
|
|
3187
3294
|
});
|
|
3188
3295
|
suite('CBOR performance tests', function(){
|
|
3189
3296
|
test('performance JSON.parse', function() {
|