msgpackr 1.9.8 → 1.10.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 +1 -0
- package/dist/index-no-eval.cjs +42 -7
- 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 +42 -7
- 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 +64 -26
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +93 -26
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +11 -0
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/pack.js +31 -7
- package/package.json +1 -1
- package/struct.js +22 -19
- package/test-worker.js +3 -0
- package/unpack.js +11 -0
package/dist/test.js
CHANGED
|
@@ -984,6 +984,17 @@
|
|
|
984
984
|
currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
985
985
|
currentExtensions[0].noBuffer = true;
|
|
986
986
|
|
|
987
|
+
currentExtensions[0x42] = (data) => {
|
|
988
|
+
// decode bigint
|
|
989
|
+
let length = data.length;
|
|
990
|
+
let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
|
|
991
|
+
for (let i = 1; i < length; i++) {
|
|
992
|
+
value <<= 8n;
|
|
993
|
+
value += BigInt(data[i]);
|
|
994
|
+
}
|
|
995
|
+
return value;
|
|
996
|
+
};
|
|
997
|
+
|
|
987
998
|
let errors = { Error, TypeError, ReferenceError };
|
|
988
999
|
currentExtensions[0x65] = () => {
|
|
989
1000
|
let data = read();
|
|
@@ -1268,6 +1279,7 @@
|
|
|
1268
1279
|
}
|
|
1269
1280
|
if (hasSharedUpdate)
|
|
1270
1281
|
hasSharedUpdate = false;
|
|
1282
|
+
let encodingError;
|
|
1271
1283
|
try {
|
|
1272
1284
|
if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
|
|
1273
1285
|
writeStruct(value);
|
|
@@ -1318,6 +1330,9 @@
|
|
|
1318
1330
|
return target
|
|
1319
1331
|
}
|
|
1320
1332
|
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
1333
|
+
} catch(error) {
|
|
1334
|
+
encodingError = error;
|
|
1335
|
+
throw error;
|
|
1321
1336
|
} finally {
|
|
1322
1337
|
if (structures) {
|
|
1323
1338
|
resetStructures();
|
|
@@ -1326,12 +1341,14 @@
|
|
|
1326
1341
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1327
1342
|
let returnBuffer = target.subarray(start, position);
|
|
1328
1343
|
let newSharedData = prepareStructures$1(structures, packr);
|
|
1329
|
-
if (
|
|
1330
|
-
|
|
1331
|
-
|
|
1344
|
+
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
|
|
1345
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
1346
|
+
// get updated structures and try again if the update failed
|
|
1347
|
+
return packr.pack(value, encodeOptions)
|
|
1348
|
+
}
|
|
1349
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1350
|
+
return returnBuffer
|
|
1332
1351
|
}
|
|
1333
|
-
packr.lastNamedStructuresLength = sharedLength;
|
|
1334
|
-
return returnBuffer
|
|
1335
1352
|
}
|
|
1336
1353
|
}
|
|
1337
1354
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
@@ -1673,8 +1690,26 @@
|
|
|
1673
1690
|
if (this.largeBigIntToFloat) {
|
|
1674
1691
|
target[position++] = 0xcb;
|
|
1675
1692
|
targetView.setFloat64(position, Number(value));
|
|
1693
|
+
} else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
|
|
1694
|
+
target[position++] = 0xc7;
|
|
1695
|
+
position++;
|
|
1696
|
+
target[position++] = 0x42; // "B" for BigInt
|
|
1697
|
+
let bytes = [];
|
|
1698
|
+
let alignedSign;
|
|
1699
|
+
do {
|
|
1700
|
+
let byte = value & 0xffn;
|
|
1701
|
+
alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
|
|
1702
|
+
bytes.push(byte);
|
|
1703
|
+
value >>= 8n;
|
|
1704
|
+
} while (!((value === 0n || value === -1n) && alignedSign));
|
|
1705
|
+
target[position-2] = bytes.length;
|
|
1706
|
+
for (let i = bytes.length; i > 0;) {
|
|
1707
|
+
target[position++] = Number(bytes[--i]);
|
|
1708
|
+
}
|
|
1709
|
+
return
|
|
1676
1710
|
} else {
|
|
1677
|
-
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format,
|
|
1711
|
+
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
1712
|
+
' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
|
|
1678
1713
|
}
|
|
1679
1714
|
}
|
|
1680
1715
|
position += 8;
|
|
@@ -1922,7 +1957,7 @@
|
|
|
1922
1957
|
}
|
|
1923
1958
|
};
|
|
1924
1959
|
const writeStruct = (object, safePrototype) => {
|
|
1925
|
-
let newPosition = writeStructSlots(object, target, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1960
|
+
let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1926
1961
|
if (notifySharedUpdate)
|
|
1927
1962
|
return hasSharedUpdate = true;
|
|
1928
1963
|
position = newPosition;
|
|
@@ -2223,7 +2258,7 @@
|
|
|
2223
2258
|
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
2224
2259
|
} : false;
|
|
2225
2260
|
setWriteStructSlots(writeStruct, prepareStructures);
|
|
2226
|
-
function writeStruct(object, target, position, structures, makeRoom, pack, packr) {
|
|
2261
|
+
function writeStruct(object, target, encodingStart, position, structures, makeRoom, pack, packr) {
|
|
2227
2262
|
let typedStructs = packr.typedStructs || (packr.typedStructs = []);
|
|
2228
2263
|
// note that we rely on pack.js to load stored structures before we get to this point
|
|
2229
2264
|
let targetView = target.dataView;
|
|
@@ -2231,12 +2266,12 @@
|
|
|
2231
2266
|
let safeEnd = target.length - 10;
|
|
2232
2267
|
let start = position;
|
|
2233
2268
|
if (position > safeEnd) {
|
|
2234
|
-
let lastStart = start;
|
|
2235
2269
|
target = makeRoom(position);
|
|
2236
2270
|
targetView = target.dataView;
|
|
2237
|
-
position -=
|
|
2238
|
-
|
|
2239
|
-
|
|
2271
|
+
position -= encodingStart;
|
|
2272
|
+
start -= encodingStart;
|
|
2273
|
+
refsStartPosition -= encodingStart;
|
|
2274
|
+
encodingStart = 0;
|
|
2240
2275
|
safeEnd = target.length - 10;
|
|
2241
2276
|
}
|
|
2242
2277
|
|
|
@@ -2274,13 +2309,13 @@
|
|
|
2274
2309
|
};
|
|
2275
2310
|
}
|
|
2276
2311
|
if (position > safeEnd) {
|
|
2277
|
-
let lastStart = start;
|
|
2278
2312
|
target = makeRoom(position);
|
|
2279
2313
|
targetView = target.dataView;
|
|
2280
|
-
position -=
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2314
|
+
position -= encodingStart;
|
|
2315
|
+
start -= encodingStart;
|
|
2316
|
+
refsStartPosition -= encodingStart;
|
|
2317
|
+
refPosition -= encodingStart;
|
|
2318
|
+
encodingStart = 0;
|
|
2284
2319
|
safeEnd = target.length - 10;
|
|
2285
2320
|
}
|
|
2286
2321
|
switch (typeof value) {
|
|
@@ -2319,13 +2354,13 @@
|
|
|
2319
2354
|
let strLength = value.length;
|
|
2320
2355
|
refOffset = refPosition - refsStartPosition;
|
|
2321
2356
|
if ((strLength << 2) + refPosition > safeEnd) {
|
|
2322
|
-
let lastStart = start;
|
|
2323
2357
|
target = makeRoom((strLength << 2) + refPosition);
|
|
2324
2358
|
targetView = target.dataView;
|
|
2325
|
-
position -=
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2359
|
+
position -= encodingStart;
|
|
2360
|
+
start -= encodingStart;
|
|
2361
|
+
refsStartPosition -= encodingStart;
|
|
2362
|
+
refPosition -= encodingStart;
|
|
2363
|
+
encodingStart = 0;
|
|
2329
2364
|
safeEnd = target.length - 10;
|
|
2330
2365
|
}
|
|
2331
2366
|
if (strLength > ((0xff00 + refOffset) >> 2)) {
|
|
@@ -2427,6 +2462,8 @@
|
|
|
2427
2462
|
position = updatedPosition;
|
|
2428
2463
|
} else queuedReferences.push(key, value, keyIndex);
|
|
2429
2464
|
break;
|
|
2465
|
+
default:
|
|
2466
|
+
queuedReferences.push(key, value, keyIndex);
|
|
2430
2467
|
}
|
|
2431
2468
|
keyIndex++;
|
|
2432
2469
|
}
|
|
@@ -2484,9 +2521,10 @@
|
|
|
2484
2521
|
refPosition = newPosition.position;
|
|
2485
2522
|
targetView = newPosition.targetView;
|
|
2486
2523
|
target = newPosition.target;
|
|
2487
|
-
refsStartPosition -=
|
|
2488
|
-
position -=
|
|
2489
|
-
start
|
|
2524
|
+
refsStartPosition -= encodingStart;
|
|
2525
|
+
position -= encodingStart;
|
|
2526
|
+
start -= encodingStart;
|
|
2527
|
+
encodingStart = 0;
|
|
2490
2528
|
} else
|
|
2491
2529
|
refPosition = newPosition;
|
|
2492
2530
|
if (size === 2) {
|
|
@@ -2560,7 +2598,7 @@
|
|
|
2560
2598
|
if (refsStartPosition === refPosition)
|
|
2561
2599
|
return position; // no refs
|
|
2562
2600
|
typedStructs.lastStringStart = position - start;
|
|
2563
|
-
return writeStruct(object, target, start, structures, makeRoom, pack, packr);
|
|
2601
|
+
return writeStruct(object, target, encodingStart, start, structures, makeRoom, pack, packr);
|
|
2564
2602
|
}
|
|
2565
2603
|
return refPosition;
|
|
2566
2604
|
}
|
|
@@ -3340,6 +3378,22 @@
|
|
|
3340
3378
|
assert.equal(pack(123).length, 1);
|
|
3341
3379
|
});
|
|
3342
3380
|
|
|
3381
|
+
test('BigInt', function() {
|
|
3382
|
+
let packr = new Packr({useBigIntExtension: true});
|
|
3383
|
+
let data = {
|
|
3384
|
+
a: 3333333333333333333333333333n,
|
|
3385
|
+
b: 1234567890123456789012345678901234567890n,
|
|
3386
|
+
c: -3333333333333333333333333333n,
|
|
3387
|
+
d: -352523523642364364364264264264264264262642642n,
|
|
3388
|
+
e: 0xffffffffffffffffffffffffffn,
|
|
3389
|
+
f: -0xffffffffffffffffffffffffffn,
|
|
3390
|
+
};
|
|
3391
|
+
let serialized = packr.pack(data);
|
|
3392
|
+
let deserialized = packr.unpack(serialized);
|
|
3393
|
+
assert.deepEqual(data, deserialized);
|
|
3394
|
+
});
|
|
3395
|
+
|
|
3396
|
+
|
|
3343
3397
|
test('extended class pack/unpack', function(){
|
|
3344
3398
|
function Extended() {
|
|
3345
3399
|
|
|
@@ -3609,6 +3663,19 @@
|
|
|
3609
3663
|
var deserialized = unpack(serialized);
|
|
3610
3664
|
assert.equal(deserialized.aDate, data.aDate.toString());
|
|
3611
3665
|
});
|
|
3666
|
+
test('standard pack fails on circular reference with shared structures', function () {
|
|
3667
|
+
var data = {};
|
|
3668
|
+
data.self = data;
|
|
3669
|
+
let structures = [];
|
|
3670
|
+
let packr = new Packr({
|
|
3671
|
+
structures,
|
|
3672
|
+
saveStructures(structures) {
|
|
3673
|
+
}
|
|
3674
|
+
});
|
|
3675
|
+
assert.throws(function () {
|
|
3676
|
+
packr.pack(data);
|
|
3677
|
+
});
|
|
3678
|
+
});
|
|
3612
3679
|
|
|
3613
3680
|
test('proto handling', function() {
|
|
3614
3681
|
var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
|