msgpackr 1.10.1 → 1.10.2

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
@@ -911,8 +911,10 @@
911
911
  }
912
912
 
913
913
  function asSafeString(property) {
914
+ // protect against expensive (DoS) string conversions
914
915
  if (typeof property === 'string') return property;
915
- if (typeof property === 'number') return property.toString();
916
+ if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
917
+ if (property == null) return property + '';
916
918
  throw new Error('Invalid property type for record', typeof property);
917
919
  }
918
920
  // the registration of the record definition extension (as "r")
@@ -952,7 +954,7 @@
952
954
  let errors = { Error, TypeError, ReferenceError };
953
955
  currentExtensions[0x65] = () => {
954
956
  let data = read();
955
- return (errors[data[0]] || Error)(data[1])
957
+ return (errors[data[0]] || Error)(data[1], { cause: data[2] })
956
958
  };
957
959
 
958
960
  currentExtensions[0x69] = (data) => {
@@ -996,8 +998,15 @@
996
998
  currentExtensions[0x74] = (data) => {
997
999
  let typeCode = data[0];
998
1000
  let typedArrayName = typedArrays[typeCode];
999
- if (!typedArrayName)
1001
+ if (!typedArrayName) {
1002
+ if (typeCode === 16) {
1003
+ let ab = new ArrayBuffer(data.length - 1);
1004
+ let u8 = new Uint8Array(ab);
1005
+ u8.set(data.subarray(1));
1006
+ return ab;
1007
+ }
1000
1008
  throw new Error('Could not find typed array for code ' + typeCode)
1009
+ }
1001
1010
  // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
1002
1011
  return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
1003
1012
  };
@@ -1293,10 +1302,14 @@
1293
1302
  return packr.pack(value, encodeOptions)
1294
1303
  }
1295
1304
  packr.lastNamedStructuresLength = sharedLength;
1305
+ // don't keep large buffers around
1306
+ if (target.length > 0x40000000) target = null;
1296
1307
  return returnBuffer
1297
1308
  }
1298
1309
  }
1299
1310
  }
1311
+ // don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
1312
+ if (target.length > 0x40000000) target = null;
1300
1313
  if (encodeOptions & RESET_BUFFER_MODE)
1301
1314
  position = start;
1302
1315
  }
@@ -1519,7 +1532,7 @@
1519
1532
  }
1520
1533
  let constructor = value.constructor;
1521
1534
  if (constructor === Object) {
1522
- writeObject(value, true);
1535
+ writeObject(value);
1523
1536
  } else if (constructor === Array) {
1524
1537
  packArray(value);
1525
1538
  } else if (constructor === Map) {
@@ -1615,8 +1628,8 @@
1615
1628
  if (type === 'function')
1616
1629
  return pack(this.writeFunction && this.writeFunction(value));
1617
1630
 
1618
- // no extension found, write as object
1619
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1631
+ // no extension found, write as plain object
1632
+ writeObject(value);
1620
1633
  }
1621
1634
  }
1622
1635
  }
@@ -1703,13 +1716,13 @@
1703
1716
  }
1704
1717
  }
1705
1718
  } :
1706
- (object, safePrototype) => {
1719
+ (object) => {
1707
1720
  target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
1708
1721
  let objectOffset = position - start;
1709
1722
  position += 2;
1710
1723
  let size = 0;
1711
1724
  for (let key in object) {
1712
- if (safePrototype || object.hasOwnProperty(key)) {
1725
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1713
1726
  pack(key);
1714
1727
  pack(object[key]);
1715
1728
  size++;
@@ -1721,12 +1734,12 @@
1721
1734
 
1722
1735
  const writeRecord = this.useRecords === false ? writePlainObject :
1723
1736
  (options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
1724
- (object, safePrototype) => {
1737
+ (object) => {
1725
1738
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1726
1739
  let objectOffset = position++ - start;
1727
1740
  let wroteKeys;
1728
1741
  for (let key in object) {
1729
- if (safePrototype || object.hasOwnProperty(key)) {
1742
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1730
1743
  nextTransition = transition[key];
1731
1744
  if (nextTransition)
1732
1745
  transition = nextTransition;
@@ -1765,10 +1778,10 @@
1765
1778
  insertNewRecord(transition, Object.keys(object), objectOffset, 0);
1766
1779
  }
1767
1780
  } :
1768
- (object, safePrototype) => {
1781
+ (object) => {
1769
1782
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1770
1783
  let newTransitions = 0;
1771
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1784
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1772
1785
  nextTransition = transition[key];
1773
1786
  if (!nextTransition) {
1774
1787
  nextTransition = transition[key] = Object.create(null);
@@ -1788,7 +1801,7 @@
1788
1801
  }
1789
1802
  // now write the values
1790
1803
  for (let key in object)
1791
- if (safePrototype || object.hasOwnProperty(key)) {
1804
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1792
1805
  pack(object[key]);
1793
1806
  }
1794
1807
  };
@@ -1796,8 +1809,8 @@
1796
1809
  // craete reference to useRecords if useRecords is a function
1797
1810
  const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
1798
1811
 
1799
- const writeObject = checkUseRecords ? (object, safePrototype) => {
1800
- checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
1812
+ const writeObject = checkUseRecords ? (object) => {
1813
+ checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
1801
1814
  } : writeRecord;
1802
1815
 
1803
1816
  const makeRoom = (end) => {
@@ -1902,7 +1915,7 @@
1902
1915
  target[insertionOffset + start] = keysTarget[0];
1903
1916
  }
1904
1917
  };
1905
- const writeStruct = (object, safePrototype) => {
1918
+ const writeStruct = (object) => {
1906
1919
  let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
1907
1920
  if (notifySharedUpdate)
1908
1921
  return hasSharedUpdate = true;
@@ -1916,7 +1929,7 @@
1916
1929
  return position;
1917
1930
  }, this);
1918
1931
  if (newPosition === 0) // bail and go to a msgpack object
1919
- return writeObject(object, true);
1932
+ return writeObject(object);
1920
1933
  position = newPosition;
1921
1934
  };
1922
1935
  }
@@ -1994,7 +2007,7 @@
1994
2007
  target[position++] = 0x65; // 'e' for error
1995
2008
  target[position++] = 0;
1996
2009
  }
1997
- pack([ error.name, error.message ]);
2010
+ pack([ error.name, error.message, error.cause ]);
1998
2011
  }
1999
2012
  }, {
2000
2013
  pack(regex, allocateForWrite, pack) {
@@ -2047,6 +2060,7 @@
2047
2060
  }
2048
2061
  target[position++] = 0x74; // "t" for typed array
2049
2062
  target[position++] = type;
2063
+ if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
2050
2064
  target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
2051
2065
  }
2052
2066
  function writeBuffer(buffer, allocateForWrite) {