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/index.js CHANGED
@@ -858,7 +858,7 @@
858
858
  return readFixedString(length)
859
859
  } else { // not cacheable, go back and do a standard read
860
860
  position$1--;
861
- return read().toString()
861
+ return asSafeString(read())
862
862
  }
863
863
  let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position$1) : length > 0 ? src[position$1] : 0)) & 0xfff;
864
864
  let entry = keyCache[key];
@@ -910,9 +910,15 @@
910
910
  return entry.string = readFixedString(length)
911
911
  }
912
912
 
913
+ function asSafeString(property) {
914
+ if (typeof property === 'string') return property;
915
+ if (typeof property === 'number') return property.toString();
916
+ throw new Error('Invalid property type for record', typeof property);
917
+ }
913
918
  // the registration of the record definition extension (as "r")
914
919
  const recordDefinition = (id, highByte) => {
915
- let structure = read().map(property => property.toString()); // ensure that all keys are strings and that the array is mutable
920
+ let structure = read().map(asSafeString); // ensure that all keys are strings and
921
+ // that the array is mutable
916
922
  let firstByte = id;
917
923
  if (highByte !== undefined) {
918
924
  id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
@@ -932,6 +938,17 @@
932
938
  currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
933
939
  currentExtensions[0].noBuffer = true;
934
940
 
941
+ currentExtensions[0x42] = (data) => {
942
+ // decode bigint
943
+ let length = data.length;
944
+ let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
945
+ for (let i = 1; i < length; i++) {
946
+ value <<= 8n;
947
+ value += BigInt(data[i]);
948
+ }
949
+ return value;
950
+ };
951
+
935
952
  let errors = { Error, TypeError, ReferenceError };
936
953
  currentExtensions[0x65] = () => {
937
954
  let data = read();
@@ -940,6 +957,7 @@
940
957
 
941
958
  currentExtensions[0x69] = (data) => {
942
959
  // id extension (for structured clones)
960
+ if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
943
961
  let id = dataView.getUint32(position$1 - 4);
944
962
  if (!referenceMap)
945
963
  referenceMap = new Map();
@@ -963,6 +981,7 @@
963
981
 
964
982
  currentExtensions[0x70] = (data) => {
965
983
  // pointer extension (for structured clones)
984
+ if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
966
985
  let id = dataView.getUint32(position$1 - 4);
967
986
  let refEntry = referenceMap.get(id);
968
987
  refEntry.used = true;
@@ -1206,6 +1225,7 @@
1206
1225
  }
1207
1226
  if (hasSharedUpdate)
1208
1227
  hasSharedUpdate = false;
1228
+ let encodingError;
1209
1229
  try {
1210
1230
  if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
1211
1231
  writeStruct(value);
@@ -1256,6 +1276,9 @@
1256
1276
  return target
1257
1277
  }
1258
1278
  return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
1279
+ } catch(error) {
1280
+ encodingError = error;
1281
+ throw error;
1259
1282
  } finally {
1260
1283
  if (structures) {
1261
1284
  resetStructures();
@@ -1264,12 +1287,14 @@
1264
1287
  // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1265
1288
  let returnBuffer = target.subarray(start, position);
1266
1289
  let newSharedData = prepareStructures(structures, packr);
1267
- if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1268
- // get updated structures and try again if the update failed
1269
- return packr.pack(value, encodeOptions)
1290
+ if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
1291
+ if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
1292
+ // get updated structures and try again if the update failed
1293
+ return packr.pack(value, encodeOptions)
1294
+ }
1295
+ packr.lastNamedStructuresLength = sharedLength;
1296
+ return returnBuffer
1270
1297
  }
1271
- packr.lastNamedStructuresLength = sharedLength;
1272
- return returnBuffer
1273
1298
  }
1274
1299
  }
1275
1300
  if (encodeOptions & RESET_BUFFER_MODE)
@@ -1611,8 +1636,26 @@
1611
1636
  if (this.largeBigIntToFloat) {
1612
1637
  target[position++] = 0xcb;
1613
1638
  targetView.setFloat64(position, Number(value));
1639
+ } else if (this.useBigIntExtension && value < 2n**(1023n) && value > -(2n**(1023n))) {
1640
+ target[position++] = 0xc7;
1641
+ position++;
1642
+ target[position++] = 0x42; // "B" for BigInt
1643
+ let bytes = [];
1644
+ let alignedSign;
1645
+ do {
1646
+ let byte = value & 0xffn;
1647
+ alignedSign = (byte & 0x80n) === (value < 0n ? 0x80n : 0n);
1648
+ bytes.push(byte);
1649
+ value >>= 8n;
1650
+ } while (!((value === 0n || value === -1n) && alignedSign));
1651
+ target[position-2] = bytes.length;
1652
+ for (let i = bytes.length; i > 0;) {
1653
+ target[position++] = Number(bytes[--i]);
1654
+ }
1655
+ return
1614
1656
  } else {
1615
- throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1657
+ throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
1658
+ ' useBigIntExtension or set largeBigIntToFloat to convert to float-64')
1616
1659
  }
1617
1660
  }
1618
1661
  position += 8;