msgpackr 1.10.1 → 1.10.2
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 +1 -0
- package/dist/index-no-eval.cjs +32 -18
- 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 +32 -18
- 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 +32 -18
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +66 -19
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +12 -3
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +20 -15
- package/package.json +1 -1
- package/unpack.js +12 -3
package/dist/test.js
CHANGED
|
@@ -963,8 +963,10 @@
|
|
|
963
963
|
}
|
|
964
964
|
|
|
965
965
|
function asSafeString(property) {
|
|
966
|
+
// protect against expensive (DoS) string conversions
|
|
966
967
|
if (typeof property === 'string') return property;
|
|
967
|
-
if (typeof property === 'number') return property.toString();
|
|
968
|
+
if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
|
|
969
|
+
if (property == null) return property + '';
|
|
968
970
|
throw new Error('Invalid property type for record', typeof property);
|
|
969
971
|
}
|
|
970
972
|
// the registration of the record definition extension (as "r")
|
|
@@ -1004,7 +1006,7 @@
|
|
|
1004
1006
|
let errors = { Error, TypeError, ReferenceError };
|
|
1005
1007
|
currentExtensions[0x65] = () => {
|
|
1006
1008
|
let data = read();
|
|
1007
|
-
return (errors[data[0]] || Error)(data[1])
|
|
1009
|
+
return (errors[data[0]] || Error)(data[1], { cause: data[2] })
|
|
1008
1010
|
};
|
|
1009
1011
|
|
|
1010
1012
|
currentExtensions[0x69] = (data) => {
|
|
@@ -1048,8 +1050,15 @@
|
|
|
1048
1050
|
currentExtensions[0x74] = (data) => {
|
|
1049
1051
|
let typeCode = data[0];
|
|
1050
1052
|
let typedArrayName = typedArrays[typeCode];
|
|
1051
|
-
if (!typedArrayName)
|
|
1053
|
+
if (!typedArrayName) {
|
|
1054
|
+
if (typeCode === 16) {
|
|
1055
|
+
let ab = new ArrayBuffer(data.length - 1);
|
|
1056
|
+
let u8 = new Uint8Array(ab);
|
|
1057
|
+
u8.set(data.subarray(1));
|
|
1058
|
+
return ab;
|
|
1059
|
+
}
|
|
1052
1060
|
throw new Error('Could not find typed array for code ' + typeCode)
|
|
1061
|
+
}
|
|
1053
1062
|
// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
|
|
1054
1063
|
return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
|
|
1055
1064
|
};
|
|
@@ -1355,10 +1364,14 @@
|
|
|
1355
1364
|
return packr.pack(value, encodeOptions)
|
|
1356
1365
|
}
|
|
1357
1366
|
packr.lastNamedStructuresLength = sharedLength;
|
|
1367
|
+
// don't keep large buffers around
|
|
1368
|
+
if (target.length > 0x40000000) target = null;
|
|
1358
1369
|
return returnBuffer
|
|
1359
1370
|
}
|
|
1360
1371
|
}
|
|
1361
1372
|
}
|
|
1373
|
+
// don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
|
|
1374
|
+
if (target.length > 0x40000000) target = null;
|
|
1362
1375
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1363
1376
|
position = start;
|
|
1364
1377
|
}
|
|
@@ -1581,7 +1594,7 @@
|
|
|
1581
1594
|
}
|
|
1582
1595
|
let constructor = value.constructor;
|
|
1583
1596
|
if (constructor === Object) {
|
|
1584
|
-
writeObject(value
|
|
1597
|
+
writeObject(value);
|
|
1585
1598
|
} else if (constructor === Array) {
|
|
1586
1599
|
packArray(value);
|
|
1587
1600
|
} else if (constructor === Map) {
|
|
@@ -1677,8 +1690,8 @@
|
|
|
1677
1690
|
if (type === 'function')
|
|
1678
1691
|
return pack(this.writeFunction && this.writeFunction(value));
|
|
1679
1692
|
|
|
1680
|
-
// no extension found, write as object
|
|
1681
|
-
writeObject(value
|
|
1693
|
+
// no extension found, write as plain object
|
|
1694
|
+
writeObject(value);
|
|
1682
1695
|
}
|
|
1683
1696
|
}
|
|
1684
1697
|
}
|
|
@@ -1765,13 +1778,13 @@
|
|
|
1765
1778
|
}
|
|
1766
1779
|
}
|
|
1767
1780
|
} :
|
|
1768
|
-
(object
|
|
1781
|
+
(object) => {
|
|
1769
1782
|
target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
|
|
1770
1783
|
let objectOffset = position - start;
|
|
1771
1784
|
position += 2;
|
|
1772
1785
|
let size = 0;
|
|
1773
1786
|
for (let key in object) {
|
|
1774
|
-
if (
|
|
1787
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1775
1788
|
pack(key);
|
|
1776
1789
|
pack(object[key]);
|
|
1777
1790
|
size++;
|
|
@@ -1783,12 +1796,12 @@
|
|
|
1783
1796
|
|
|
1784
1797
|
const writeRecord = this.useRecords === false ? writePlainObject :
|
|
1785
1798
|
(options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
|
|
1786
|
-
(object
|
|
1799
|
+
(object) => {
|
|
1787
1800
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1788
1801
|
let objectOffset = position++ - start;
|
|
1789
1802
|
let wroteKeys;
|
|
1790
1803
|
for (let key in object) {
|
|
1791
|
-
if (
|
|
1804
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1792
1805
|
nextTransition = transition[key];
|
|
1793
1806
|
if (nextTransition)
|
|
1794
1807
|
transition = nextTransition;
|
|
@@ -1827,10 +1840,10 @@
|
|
|
1827
1840
|
insertNewRecord(transition, Object.keys(object), objectOffset, 0);
|
|
1828
1841
|
}
|
|
1829
1842
|
} :
|
|
1830
|
-
(object
|
|
1843
|
+
(object) => {
|
|
1831
1844
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1832
1845
|
let newTransitions = 0;
|
|
1833
|
-
for (let key in object) if (
|
|
1846
|
+
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1834
1847
|
nextTransition = transition[key];
|
|
1835
1848
|
if (!nextTransition) {
|
|
1836
1849
|
nextTransition = transition[key] = Object.create(null);
|
|
@@ -1850,7 +1863,7 @@
|
|
|
1850
1863
|
}
|
|
1851
1864
|
// now write the values
|
|
1852
1865
|
for (let key in object)
|
|
1853
|
-
if (
|
|
1866
|
+
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
1854
1867
|
pack(object[key]);
|
|
1855
1868
|
}
|
|
1856
1869
|
};
|
|
@@ -1858,8 +1871,8 @@
|
|
|
1858
1871
|
// craete reference to useRecords if useRecords is a function
|
|
1859
1872
|
const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
|
|
1860
1873
|
|
|
1861
|
-
const writeObject = checkUseRecords ? (object
|
|
1862
|
-
checkUseRecords(object) ? writeRecord(object
|
|
1874
|
+
const writeObject = checkUseRecords ? (object) => {
|
|
1875
|
+
checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
|
|
1863
1876
|
} : writeRecord;
|
|
1864
1877
|
|
|
1865
1878
|
const makeRoom = (end) => {
|
|
@@ -1964,7 +1977,7 @@
|
|
|
1964
1977
|
target[insertionOffset + start] = keysTarget[0];
|
|
1965
1978
|
}
|
|
1966
1979
|
};
|
|
1967
|
-
const writeStruct = (object
|
|
1980
|
+
const writeStruct = (object) => {
|
|
1968
1981
|
let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1969
1982
|
if (notifySharedUpdate)
|
|
1970
1983
|
return hasSharedUpdate = true;
|
|
@@ -1978,7 +1991,7 @@
|
|
|
1978
1991
|
return position;
|
|
1979
1992
|
}, this);
|
|
1980
1993
|
if (newPosition === 0) // bail and go to a msgpack object
|
|
1981
|
-
return writeObject(object
|
|
1994
|
+
return writeObject(object);
|
|
1982
1995
|
position = newPosition;
|
|
1983
1996
|
};
|
|
1984
1997
|
}
|
|
@@ -2056,7 +2069,7 @@
|
|
|
2056
2069
|
target[position++] = 0x65; // 'e' for error
|
|
2057
2070
|
target[position++] = 0;
|
|
2058
2071
|
}
|
|
2059
|
-
pack([ error.name, error.message ]);
|
|
2072
|
+
pack([ error.name, error.message, error.cause ]);
|
|
2060
2073
|
}
|
|
2061
2074
|
}, {
|
|
2062
2075
|
pack(regex, allocateForWrite, pack) {
|
|
@@ -2109,6 +2122,7 @@
|
|
|
2109
2122
|
}
|
|
2110
2123
|
target[position++] = 0x74; // "t" for typed array
|
|
2111
2124
|
target[position++] = type;
|
|
2125
|
+
if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
|
|
2112
2126
|
target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
|
|
2113
2127
|
}
|
|
2114
2128
|
function writeBuffer(buffer, allocateForWrite) {
|
|
@@ -3711,13 +3725,35 @@
|
|
|
3711
3725
|
}
|
|
3712
3726
|
});
|
|
3713
3727
|
|
|
3728
|
+
test('moreTyesp: Error with causes', function() {
|
|
3729
|
+
const object = {
|
|
3730
|
+
error: new Error('test'),
|
|
3731
|
+
errorWithCause: new Error('test-1', { cause: new Error('test-2')}),
|
|
3732
|
+
};
|
|
3733
|
+
const packr = new Packr({
|
|
3734
|
+
moreTypes: true,
|
|
3735
|
+
});
|
|
3736
|
+
|
|
3737
|
+
const serialized = packr.pack(object);
|
|
3738
|
+
const deserialized = packr.unpack(serialized);
|
|
3739
|
+
assert.equal(deserialized.error.message, object.error.message);
|
|
3740
|
+
assert.equal(deserialized.error.cause, object.error.cause);
|
|
3741
|
+
assert.equal(deserialized.errorWithCause.message, object.errorWithCause.message);
|
|
3742
|
+
assert.equal(deserialized.errorWithCause.cause.message, object.errorWithCause.cause.message);
|
|
3743
|
+
assert.equal(deserialized.errorWithCause.cause.cause, object.errorWithCause.cause.cause);
|
|
3744
|
+
});
|
|
3745
|
+
|
|
3714
3746
|
test('structured cloning: self reference', function() {
|
|
3715
3747
|
let object = {
|
|
3716
3748
|
test: 'string',
|
|
3717
3749
|
children: [
|
|
3718
3750
|
{ name: 'child' }
|
|
3719
|
-
]
|
|
3751
|
+
],
|
|
3752
|
+
value: new ArrayBuffer(10)
|
|
3720
3753
|
};
|
|
3754
|
+
let u8 = new Uint8Array(object.value);
|
|
3755
|
+
u8[0] = 1;
|
|
3756
|
+
u8[1] = 2;
|
|
3721
3757
|
object.self = object;
|
|
3722
3758
|
object.children[1] = object;
|
|
3723
3759
|
object.children[2] = object.children[0];
|
|
@@ -3733,6 +3769,10 @@
|
|
|
3733
3769
|
assert.equal(deserialized.children[1], deserialized);
|
|
3734
3770
|
assert.equal(deserialized.children[0], deserialized.children[2]);
|
|
3735
3771
|
assert.equal(deserialized.children, deserialized.childrenAgain);
|
|
3772
|
+
assert.equal(deserialized.value.constructor.name, 'ArrayBuffer');
|
|
3773
|
+
u8 = new Uint8Array(deserialized.value);
|
|
3774
|
+
assert.equal(u8[0], 1);
|
|
3775
|
+
assert.equal(u8[1], 2);
|
|
3736
3776
|
});
|
|
3737
3777
|
|
|
3738
3778
|
test('structured cloning: types', function() {
|
|
@@ -3813,6 +3853,13 @@
|
|
|
3813
3853
|
assert.deepEqual(deserialized, data);
|
|
3814
3854
|
});
|
|
3815
3855
|
|
|
3856
|
+
test('object with __proto__', function(){
|
|
3857
|
+
const data = { foo: 'bar', __proto__: { isAdmin: true } };
|
|
3858
|
+
var serialized = pack(data);
|
|
3859
|
+
var deserialized = unpack(serialized);
|
|
3860
|
+
assert.deepEqual(deserialized, { foo: 'bar' });
|
|
3861
|
+
});
|
|
3862
|
+
|
|
3816
3863
|
test('separate instances', function() {
|
|
3817
3864
|
const packr = new Packr({
|
|
3818
3865
|
structures: [['m', 'e'], ['action', 'share']]
|