msgpackr 1.9.9 → 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/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 (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1330
- // get updated structures and try again if the update failed
1331
- return packr.pack(value, encodeOptions)
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, set largeBigIntToFloat to convert to float-64')
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;
@@ -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
  }
@@ -3341,6 +3378,22 @@
3341
3378
  assert.equal(pack(123).length, 1);
3342
3379
  });
3343
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
+
3344
3397
  test('extended class pack/unpack', function(){
3345
3398
  function Extended() {
3346
3399
 
@@ -3610,6 +3663,19 @@
3610
3663
  var deserialized = unpack(serialized);
3611
3664
  assert.equal(deserialized.aDate, data.aDate.toString());
3612
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
+ });
3613
3679
 
3614
3680
  test('proto handling', function() {
3615
3681
  var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');