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/dist/node.cjs CHANGED
@@ -914,7 +914,7 @@ function readKey() {
914
914
  return readFixedString(length)
915
915
  } else { // not cacheable, go back and do a standard read
916
916
  position$1--;
917
- return read().toString()
917
+ return asSafeString(read())
918
918
  }
919
919
  let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position$1) : length > 0 ? src[position$1] : 0)) & 0xfff;
920
920
  let entry = keyCache[key];
@@ -966,9 +966,15 @@ function readKey() {
966
966
  return entry.string = readFixedString(length)
967
967
  }
968
968
 
969
+ function asSafeString(property) {
970
+ if (typeof property === 'string') return property;
971
+ if (typeof property === 'number') return property.toString();
972
+ throw new Error('Invalid property type for record', typeof property);
973
+ }
969
974
  // the registration of the record definition extension (as "r")
970
975
  const recordDefinition = (id, highByte) => {
971
- let structure = read().map(property => property.toString()); // ensure that all keys are strings and that the array is mutable
976
+ let structure = read().map(asSafeString); // ensure that all keys are strings and
977
+ // that the array is mutable
972
978
  let firstByte = id;
973
979
  if (highByte !== undefined) {
974
980
  id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
@@ -988,6 +994,17 @@ const recordDefinition = (id, highByte) => {
988
994
  currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
989
995
  currentExtensions[0].noBuffer = true;
990
996
 
997
+ currentExtensions[0x42] = (data) => {
998
+ // decode bigint
999
+ let length = data.length;
1000
+ let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
1001
+ for (let i = 1; i < length; i++) {
1002
+ value <<= 8n;
1003
+ value += BigInt(data[i]);
1004
+ }
1005
+ return value;
1006
+ };
1007
+
991
1008
  let errors = { Error, TypeError, ReferenceError };
992
1009
  currentExtensions[0x65] = () => {
993
1010
  let data = read();
@@ -996,6 +1013,7 @@ currentExtensions[0x65] = () => {
996
1013
 
997
1014
  currentExtensions[0x69] = (data) => {
998
1015
  // id extension (for structured clones)
1016
+ if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
999
1017
  let id = dataView.getUint32(position$1 - 4);
1000
1018
  if (!referenceMap)
1001
1019
  referenceMap = new Map();
@@ -1019,6 +1037,7 @@ currentExtensions[0x69] = (data) => {
1019
1037
 
1020
1038
  currentExtensions[0x70] = (data) => {
1021
1039
  // pointer extension (for structured clones)
1040
+ if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
1022
1041
  let id = dataView.getUint32(position$1 - 4);
1023
1042
  let refEntry = referenceMap.get(id);
1024
1043
  refEntry.used = true;
@@ -1273,6 +1292,7 @@ class Packr extends Unpackr {
1273
1292
  }
1274
1293
  if (hasSharedUpdate)
1275
1294
  hasSharedUpdate = false;
1295
+ let encodingError;
1276
1296
  try {
1277
1297
  if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
1278
1298
  writeStruct(value);
@@ -1323,6 +1343,9 @@ class Packr extends Unpackr {
1323
1343
  return target
1324
1344
  }
1325
1345
  return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
1346
+ } catch(error) {
1347
+ encodingError = error;
1348
+ throw error;
1326
1349
  } finally {
1327
1350
  if (structures) {
1328
1351
  resetStructures();
@@ -1331,12 +1354,14 @@ class Packr extends Unpackr {
1331
1354
  // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1332
1355
  let returnBuffer = target.subarray(start, position);
1333
1356
  let newSharedData = prepareStructures$1(structures, packr);
1334
- if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1335
- // get updated structures and try again if the update failed
1336
- return packr.pack(value, encodeOptions)
1357
+ if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
1358
+ if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1359
+ // get updated structures and try again if the update failed
1360
+ return packr.pack(value, encodeOptions)
1361
+ }
1362
+ packr.lastNamedStructuresLength = sharedLength;
1363
+ return returnBuffer
1337
1364
  }
1338
- packr.lastNamedStructuresLength = sharedLength;
1339
- return returnBuffer
1340
1365
  }
1341
1366
  }
1342
1367
  if (encodeOptions & RESET_BUFFER_MODE)
@@ -1678,8 +1703,26 @@ class Packr extends Unpackr {
1678
1703
  if (this.largeBigIntToFloat) {
1679
1704
  target[position++] = 0xcb;
1680
1705
  targetView.setFloat64(position, Number(value));
1706
+ } else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
1707
+ target[position++] = 0xc7;
1708
+ position++;
1709
+ target[position++] = 0x42; // "B" for BigInt
1710
+ let bytes = [];
1711
+ let alignedSign;
1712
+ do {
1713
+ let byte = value & 0xffn;
1714
+ alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
1715
+ bytes.push(byte);
1716
+ value >>= 8n;
1717
+ } while (!((value === 0n || value === -1n) && alignedSign));
1718
+ target[position-2] = bytes.length;
1719
+ for (let i = bytes.length; i > 0;) {
1720
+ target[position++] = Number(bytes[--i]);
1721
+ }
1722
+ return
1681
1723
  } else {
1682
- throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1724
+ throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
1725
+ ' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
1683
1726
  }
1684
1727
  }
1685
1728
  position += 8;
@@ -2434,6 +2477,8 @@ function writeStruct(object, target, encodingStart, position, structures, makeRo
2434
2477
  position = updatedPosition;
2435
2478
  } else queuedReferences.push(key, value, keyIndex);
2436
2479
  break;
2480
+ default:
2481
+ queuedReferences.push(key, value, keyIndex);
2437
2482
  }
2438
2483
  keyIndex++;
2439
2484
  }