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/test.js CHANGED
@@ -963,8 +963,10 @@
963
963
  }
964
964
 
965
965
  function asSafeString(property) {
966
+ // protect against expensive (DoS) string conversions
966
967
  if (typeof property === 'string') return property;
967
- if (typeof property === 'number') return property.toString();
968
+ if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
969
+ if (property == null) return property + '';
968
970
  throw new Error('Invalid property type for record', typeof property);
969
971
  }
970
972
  // the registration of the record definition extension (as "r")
@@ -1004,7 +1006,7 @@
1004
1006
  let errors = { Error, TypeError, ReferenceError };
1005
1007
  currentExtensions[0x65] = () => {
1006
1008
  let data = read();
1007
- return (errors[data[0]] || Error)(data[1])
1009
+ return (errors[data[0]] || Error)(data[1], { cause: data[2] })
1008
1010
  };
1009
1011
 
1010
1012
  currentExtensions[0x69] = (data) => {
@@ -1048,8 +1050,15 @@
1048
1050
  currentExtensions[0x74] = (data) => {
1049
1051
  let typeCode = data[0];
1050
1052
  let typedArrayName = typedArrays[typeCode];
1051
- if (!typedArrayName)
1053
+ if (!typedArrayName) {
1054
+ if (typeCode === 16) {
1055
+ let ab = new ArrayBuffer(data.length - 1);
1056
+ let u8 = new Uint8Array(ab);
1057
+ u8.set(data.subarray(1));
1058
+ return ab;
1059
+ }
1052
1060
  throw new Error('Could not find typed array for code ' + typeCode)
1061
+ }
1053
1062
  // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
1054
1063
  return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
1055
1064
  };
@@ -1355,10 +1364,14 @@
1355
1364
  return packr.pack(value, encodeOptions)
1356
1365
  }
1357
1366
  packr.lastNamedStructuresLength = sharedLength;
1367
+ // don't keep large buffers around
1368
+ if (target.length > 0x40000000) target = null;
1358
1369
  return returnBuffer
1359
1370
  }
1360
1371
  }
1361
1372
  }
1373
+ // don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
1374
+ if (target.length > 0x40000000) target = null;
1362
1375
  if (encodeOptions & RESET_BUFFER_MODE)
1363
1376
  position = start;
1364
1377
  }
@@ -1581,7 +1594,7 @@
1581
1594
  }
1582
1595
  let constructor = value.constructor;
1583
1596
  if (constructor === Object) {
1584
- writeObject(value, true);
1597
+ writeObject(value);
1585
1598
  } else if (constructor === Array) {
1586
1599
  packArray(value);
1587
1600
  } else if (constructor === Map) {
@@ -1677,8 +1690,8 @@
1677
1690
  if (type === 'function')
1678
1691
  return pack(this.writeFunction && this.writeFunction(value));
1679
1692
 
1680
- // no extension found, write as object
1681
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1693
+ // no extension found, write as plain object
1694
+ writeObject(value);
1682
1695
  }
1683
1696
  }
1684
1697
  }
@@ -1765,13 +1778,13 @@
1765
1778
  }
1766
1779
  }
1767
1780
  } :
1768
- (object, safePrototype) => {
1781
+ (object) => {
1769
1782
  target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
1770
1783
  let objectOffset = position - start;
1771
1784
  position += 2;
1772
1785
  let size = 0;
1773
1786
  for (let key in object) {
1774
- if (safePrototype || object.hasOwnProperty(key)) {
1787
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1775
1788
  pack(key);
1776
1789
  pack(object[key]);
1777
1790
  size++;
@@ -1783,12 +1796,12 @@
1783
1796
 
1784
1797
  const writeRecord = this.useRecords === false ? writePlainObject :
1785
1798
  (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)
1786
- (object, safePrototype) => {
1799
+ (object) => {
1787
1800
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1788
1801
  let objectOffset = position++ - start;
1789
1802
  let wroteKeys;
1790
1803
  for (let key in object) {
1791
- if (safePrototype || object.hasOwnProperty(key)) {
1804
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1792
1805
  nextTransition = transition[key];
1793
1806
  if (nextTransition)
1794
1807
  transition = nextTransition;
@@ -1827,10 +1840,10 @@
1827
1840
  insertNewRecord(transition, Object.keys(object), objectOffset, 0);
1828
1841
  }
1829
1842
  } :
1830
- (object, safePrototype) => {
1843
+ (object) => {
1831
1844
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1832
1845
  let newTransitions = 0;
1833
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1846
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1834
1847
  nextTransition = transition[key];
1835
1848
  if (!nextTransition) {
1836
1849
  nextTransition = transition[key] = Object.create(null);
@@ -1850,7 +1863,7 @@
1850
1863
  }
1851
1864
  // now write the values
1852
1865
  for (let key in object)
1853
- if (safePrototype || object.hasOwnProperty(key)) {
1866
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1854
1867
  pack(object[key]);
1855
1868
  }
1856
1869
  };
@@ -1858,8 +1871,8 @@
1858
1871
  // craete reference to useRecords if useRecords is a function
1859
1872
  const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
1860
1873
 
1861
- const writeObject = checkUseRecords ? (object, safePrototype) => {
1862
- checkUseRecords(object) ? writeRecord(object,safePrototype) : writePlainObject(object,safePrototype);
1874
+ const writeObject = checkUseRecords ? (object) => {
1875
+ checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
1863
1876
  } : writeRecord;
1864
1877
 
1865
1878
  const makeRoom = (end) => {
@@ -1964,7 +1977,7 @@
1964
1977
  target[insertionOffset + start] = keysTarget[0];
1965
1978
  }
1966
1979
  };
1967
- const writeStruct = (object, safePrototype) => {
1980
+ const writeStruct = (object) => {
1968
1981
  let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
1969
1982
  if (notifySharedUpdate)
1970
1983
  return hasSharedUpdate = true;
@@ -1978,7 +1991,7 @@
1978
1991
  return position;
1979
1992
  }, this);
1980
1993
  if (newPosition === 0) // bail and go to a msgpack object
1981
- return writeObject(object, true);
1994
+ return writeObject(object);
1982
1995
  position = newPosition;
1983
1996
  };
1984
1997
  }
@@ -2056,7 +2069,7 @@
2056
2069
  target[position++] = 0x65; // 'e' for error
2057
2070
  target[position++] = 0;
2058
2071
  }
2059
- pack([ error.name, error.message ]);
2072
+ pack([ error.name, error.message, error.cause ]);
2060
2073
  }
2061
2074
  }, {
2062
2075
  pack(regex, allocateForWrite, pack) {
@@ -2109,6 +2122,7 @@
2109
2122
  }
2110
2123
  target[position++] = 0x74; // "t" for typed array
2111
2124
  target[position++] = type;
2125
+ if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
2112
2126
  target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
2113
2127
  }
2114
2128
  function writeBuffer(buffer, allocateForWrite) {
@@ -3711,13 +3725,35 @@
3711
3725
  }
3712
3726
  });
3713
3727
 
3728
+ test('moreTyesp: Error with causes', function() {
3729
+ const object = {
3730
+ error: new Error('test'),
3731
+ errorWithCause: new Error('test-1', { cause: new Error('test-2')}),
3732
+ };
3733
+ const packr = new Packr({
3734
+ moreTypes: true,
3735
+ });
3736
+
3737
+ const serialized = packr.pack(object);
3738
+ const deserialized = packr.unpack(serialized);
3739
+ assert.equal(deserialized.error.message, object.error.message);
3740
+ assert.equal(deserialized.error.cause, object.error.cause);
3741
+ assert.equal(deserialized.errorWithCause.message, object.errorWithCause.message);
3742
+ assert.equal(deserialized.errorWithCause.cause.message, object.errorWithCause.cause.message);
3743
+ assert.equal(deserialized.errorWithCause.cause.cause, object.errorWithCause.cause.cause);
3744
+ });
3745
+
3714
3746
  test('structured cloning: self reference', function() {
3715
3747
  let object = {
3716
3748
  test: 'string',
3717
3749
  children: [
3718
3750
  { name: 'child' }
3719
- ]
3751
+ ],
3752
+ value: new ArrayBuffer(10)
3720
3753
  };
3754
+ let u8 = new Uint8Array(object.value);
3755
+ u8[0] = 1;
3756
+ u8[1] = 2;
3721
3757
  object.self = object;
3722
3758
  object.children[1] = object;
3723
3759
  object.children[2] = object.children[0];
@@ -3733,6 +3769,10 @@
3733
3769
  assert.equal(deserialized.children[1], deserialized);
3734
3770
  assert.equal(deserialized.children[0], deserialized.children[2]);
3735
3771
  assert.equal(deserialized.children, deserialized.childrenAgain);
3772
+ assert.equal(deserialized.value.constructor.name, 'ArrayBuffer');
3773
+ u8 = new Uint8Array(deserialized.value);
3774
+ assert.equal(u8[0], 1);
3775
+ assert.equal(u8[1], 2);
3736
3776
  });
3737
3777
 
3738
3778
  test('structured cloning: types', function() {
@@ -3813,6 +3853,13 @@
3813
3853
  assert.deepEqual(deserialized, data);
3814
3854
  });
3815
3855
 
3856
+ test('object with __proto__', function(){
3857
+ const data = { foo: 'bar', __proto__: { isAdmin: true } };
3858
+ var serialized = pack(data);
3859
+ var deserialized = unpack(serialized);
3860
+ assert.deepEqual(deserialized, { foo: 'bar' });
3861
+ });
3862
+
3816
3863
  test('separate instances', function() {
3817
3864
  const packr = new Packr({
3818
3865
  structures: [['m', 'e'], ['action', 'share']]