msgpackr 1.9.9 → 1.10.1
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 +51 -8
- 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 +51 -8
- 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 +53 -8
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +82 -8
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +21 -2
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +30 -6
- package/package.json +1 -1
- package/struct.js +2 -0
- package/test-worker.js +3 -0
- package/unpack.js +21 -2
package/dist/test.js
CHANGED
|
@@ -910,7 +910,7 @@
|
|
|
910
910
|
return readFixedString(length)
|
|
911
911
|
} else { // not cacheable, go back and do a standard read
|
|
912
912
|
position$1--;
|
|
913
|
-
return read()
|
|
913
|
+
return asSafeString(read())
|
|
914
914
|
}
|
|
915
915
|
let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position$1) : length > 0 ? src[position$1] : 0)) & 0xfff;
|
|
916
916
|
let entry = keyCache[key];
|
|
@@ -962,9 +962,15 @@
|
|
|
962
962
|
return entry.string = readFixedString(length)
|
|
963
963
|
}
|
|
964
964
|
|
|
965
|
+
function asSafeString(property) {
|
|
966
|
+
if (typeof property === 'string') return property;
|
|
967
|
+
if (typeof property === 'number') return property.toString();
|
|
968
|
+
throw new Error('Invalid property type for record', typeof property);
|
|
969
|
+
}
|
|
965
970
|
// the registration of the record definition extension (as "r")
|
|
966
971
|
const recordDefinition = (id, highByte) => {
|
|
967
|
-
let structure = read().map(
|
|
972
|
+
let structure = read().map(asSafeString); // ensure that all keys are strings and
|
|
973
|
+
// that the array is mutable
|
|
968
974
|
let firstByte = id;
|
|
969
975
|
if (highByte !== undefined) {
|
|
970
976
|
id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
|
|
@@ -984,6 +990,17 @@
|
|
|
984
990
|
currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
985
991
|
currentExtensions[0].noBuffer = true;
|
|
986
992
|
|
|
993
|
+
currentExtensions[0x42] = (data) => {
|
|
994
|
+
// decode bigint
|
|
995
|
+
let length = data.length;
|
|
996
|
+
let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
|
|
997
|
+
for (let i = 1; i < length; i++) {
|
|
998
|
+
value <<= 8n;
|
|
999
|
+
value += BigInt(data[i]);
|
|
1000
|
+
}
|
|
1001
|
+
return value;
|
|
1002
|
+
};
|
|
1003
|
+
|
|
987
1004
|
let errors = { Error, TypeError, ReferenceError };
|
|
988
1005
|
currentExtensions[0x65] = () => {
|
|
989
1006
|
let data = read();
|
|
@@ -992,6 +1009,7 @@
|
|
|
992
1009
|
|
|
993
1010
|
currentExtensions[0x69] = (data) => {
|
|
994
1011
|
// id extension (for structured clones)
|
|
1012
|
+
if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
|
|
995
1013
|
let id = dataView.getUint32(position$1 - 4);
|
|
996
1014
|
if (!referenceMap)
|
|
997
1015
|
referenceMap = new Map();
|
|
@@ -1015,6 +1033,7 @@
|
|
|
1015
1033
|
|
|
1016
1034
|
currentExtensions[0x70] = (data) => {
|
|
1017
1035
|
// pointer extension (for structured clones)
|
|
1036
|
+
if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
|
|
1018
1037
|
let id = dataView.getUint32(position$1 - 4);
|
|
1019
1038
|
let refEntry = referenceMap.get(id);
|
|
1020
1039
|
refEntry.used = true;
|
|
@@ -1268,6 +1287,7 @@
|
|
|
1268
1287
|
}
|
|
1269
1288
|
if (hasSharedUpdate)
|
|
1270
1289
|
hasSharedUpdate = false;
|
|
1290
|
+
let encodingError;
|
|
1271
1291
|
try {
|
|
1272
1292
|
if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
|
|
1273
1293
|
writeStruct(value);
|
|
@@ -1318,6 +1338,9 @@
|
|
|
1318
1338
|
return target
|
|
1319
1339
|
}
|
|
1320
1340
|
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
1341
|
+
} catch(error) {
|
|
1342
|
+
encodingError = error;
|
|
1343
|
+
throw error;
|
|
1321
1344
|
} finally {
|
|
1322
1345
|
if (structures) {
|
|
1323
1346
|
resetStructures();
|
|
@@ -1326,12 +1349,14 @@
|
|
|
1326
1349
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1327
1350
|
let returnBuffer = target.subarray(start, position);
|
|
1328
1351
|
let newSharedData = prepareStructures$1(structures, packr);
|
|
1329
|
-
if (
|
|
1330
|
-
|
|
1331
|
-
|
|
1352
|
+
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
|
|
1353
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
1354
|
+
// get updated structures and try again if the update failed
|
|
1355
|
+
return packr.pack(value, encodeOptions)
|
|
1356
|
+
}
|
|
1357
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1358
|
+
return returnBuffer
|
|
1332
1359
|
}
|
|
1333
|
-
packr.lastNamedStructuresLength = sharedLength;
|
|
1334
|
-
return returnBuffer
|
|
1335
1360
|
}
|
|
1336
1361
|
}
|
|
1337
1362
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
@@ -1673,8 +1698,26 @@
|
|
|
1673
1698
|
if (this.largeBigIntToFloat) {
|
|
1674
1699
|
target[position++] = 0xcb;
|
|
1675
1700
|
targetView.setFloat64(position, Number(value));
|
|
1701
|
+
} else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
|
|
1702
|
+
target[position++] = 0xc7;
|
|
1703
|
+
position++;
|
|
1704
|
+
target[position++] = 0x42; // "B" for BigInt
|
|
1705
|
+
let bytes = [];
|
|
1706
|
+
let alignedSign;
|
|
1707
|
+
do {
|
|
1708
|
+
let byte = value & 0xffn;
|
|
1709
|
+
alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
|
|
1710
|
+
bytes.push(byte);
|
|
1711
|
+
value >>= 8n;
|
|
1712
|
+
} while (!((value === 0n || value === -1n) && alignedSign));
|
|
1713
|
+
target[position-2] = bytes.length;
|
|
1714
|
+
for (let i = bytes.length; i > 0;) {
|
|
1715
|
+
target[position++] = Number(bytes[--i]);
|
|
1716
|
+
}
|
|
1717
|
+
return
|
|
1676
1718
|
} else {
|
|
1677
|
-
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format,
|
|
1719
|
+
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
1720
|
+
' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
|
|
1678
1721
|
}
|
|
1679
1722
|
}
|
|
1680
1723
|
position += 8;
|
|
@@ -2427,6 +2470,8 @@
|
|
|
2427
2470
|
position = updatedPosition;
|
|
2428
2471
|
} else queuedReferences.push(key, value, keyIndex);
|
|
2429
2472
|
break;
|
|
2473
|
+
default:
|
|
2474
|
+
queuedReferences.push(key, value, keyIndex);
|
|
2430
2475
|
}
|
|
2431
2476
|
keyIndex++;
|
|
2432
2477
|
}
|
|
@@ -3341,6 +3386,22 @@
|
|
|
3341
3386
|
assert.equal(pack(123).length, 1);
|
|
3342
3387
|
});
|
|
3343
3388
|
|
|
3389
|
+
test('BigInt', function() {
|
|
3390
|
+
let packr = new Packr({useBigIntExtension: true});
|
|
3391
|
+
let data = {
|
|
3392
|
+
a: 3333333333333333333333333333n,
|
|
3393
|
+
b: 1234567890123456789012345678901234567890n,
|
|
3394
|
+
c: -3333333333333333333333333333n,
|
|
3395
|
+
d: -352523523642364364364264264264264264262642642n,
|
|
3396
|
+
e: 0xffffffffffffffffffffffffffn,
|
|
3397
|
+
f: -0xffffffffffffffffffffffffffn,
|
|
3398
|
+
};
|
|
3399
|
+
let serialized = packr.pack(data);
|
|
3400
|
+
let deserialized = packr.unpack(serialized);
|
|
3401
|
+
assert.deepEqual(data, deserialized);
|
|
3402
|
+
});
|
|
3403
|
+
|
|
3404
|
+
|
|
3344
3405
|
test('extended class pack/unpack', function(){
|
|
3345
3406
|
function Extended() {
|
|
3346
3407
|
|
|
@@ -3610,6 +3671,19 @@
|
|
|
3610
3671
|
var deserialized = unpack(serialized);
|
|
3611
3672
|
assert.equal(deserialized.aDate, data.aDate.toString());
|
|
3612
3673
|
});
|
|
3674
|
+
test('standard pack fails on circular reference with shared structures', function () {
|
|
3675
|
+
var data = {};
|
|
3676
|
+
data.self = data;
|
|
3677
|
+
let structures = [];
|
|
3678
|
+
let packr = new Packr({
|
|
3679
|
+
structures,
|
|
3680
|
+
saveStructures(structures) {
|
|
3681
|
+
}
|
|
3682
|
+
});
|
|
3683
|
+
assert.throws(function () {
|
|
3684
|
+
packr.pack(data);
|
|
3685
|
+
});
|
|
3686
|
+
});
|
|
3613
3687
|
|
|
3614
3688
|
test('proto handling', function() {
|
|
3615
3689
|
var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
|