cbor-x 1.5.8 → 1.5.9

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.
@@ -500,7 +500,8 @@
500
500
  function safeKey(key) {
501
501
  // protect against prototype pollution
502
502
  if (typeof key === 'string') return key === '__proto__' ? '__proto_' : key
503
- if (typeof key !== 'object') return key.toString()
503
+ if (typeof key === 'number' || typeof key === 'boolean' || typeof key === 'bigint') return key.toString();
504
+ if (key == null) return key + '';
504
505
  // protect against expensive (DoS) string conversions
505
506
  throw new Error('Invalid property name type ' + typeof key);
506
507
  }
@@ -885,6 +886,7 @@
885
886
  referenceMap.id = 0;
886
887
  }
887
888
  let id = referenceMap.id++;
889
+ let startingPosition = position$1;
888
890
  let token = src[position$1];
889
891
  let target;
890
892
  // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
@@ -897,8 +899,20 @@
897
899
  let refEntry = { target }; // a placeholder object
898
900
  referenceMap.set(id, refEntry);
899
901
  let targetProperties = read(); // read the next value as the target object to id
900
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
902
+ if (refEntry.used) {// there is a cycle, so we have to assign properties to original target
903
+ if (Object.getPrototypeOf(target) !== Object.getPrototypeOf(targetProperties)) {
904
+ // this means that the returned target does not match the targetProperties, so we need rerun the read to
905
+ // have the correctly create instance be assigned as a reference, then we do the copy the properties back to the
906
+ // target
907
+ // reset the position so that the read can be repeated
908
+ position$1 = startingPosition;
909
+ // the returned instance is our new target for references
910
+ target = targetProperties;
911
+ referenceMap.set(id, { target });
912
+ targetProperties = read();
913
+ }
901
914
  return Object.assign(target, targetProperties)
915
+ }
902
916
  refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
903
917
  return targetProperties // no cycle, can just use the returned read object
904
918
  };
@@ -980,7 +994,7 @@
980
994
  for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
981
995
  if (!littleEndian && bytesPerElement == 1)
982
996
  continue
983
- let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
997
+ let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : bytesPerElement == 8 ? 3 : 0;
984
998
  currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine$1) ? (buffer) => {
985
999
  if (!TypedArray)
986
1000
  throw new Error('Could not find typed array for code ' + tag)
@@ -990,7 +1004,7 @@
990
1004
  bytesPerElement === 2 && !(buffer.byteOffset & 1) ||
991
1005
  bytesPerElement === 4 && !(buffer.byteOffset & 3) ||
992
1006
  bytesPerElement === 8 && !(buffer.byteOffset & 7))
993
- return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
1007
+ return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength >> sizeShift);
994
1008
  }
995
1009
  // we have to slice/copy here to get a new ArrayBuffer, if we are not word/byte aligned
996
1010
  return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
@@ -1590,7 +1604,7 @@
1590
1604
  }
1591
1605
  let constructor = value.constructor;
1592
1606
  if (constructor === Object) {
1593
- writeObject(value, true);
1607
+ writeObject(value);
1594
1608
  } else if (constructor === Array) {
1595
1609
  length = value.length;
1596
1610
  if (length < 0x18) {
@@ -1685,8 +1699,8 @@
1685
1699
  return encode(json)
1686
1700
  }
1687
1701
 
1688
- // no extension found, write as object
1689
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1702
+ // no extension found, write as a plain object
1703
+ writeObject(value);
1690
1704
  }
1691
1705
  }
1692
1706
  } else if (type === 'boolean') {
@@ -1748,19 +1762,19 @@
1748
1762
  }
1749
1763
  }
1750
1764
  } :
1751
- (object, safePrototype) => {
1765
+ (object) => {
1752
1766
  target[position++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1753
1767
  let objectOffset = position - start;
1754
1768
  position += 2;
1755
1769
  let size = 0;
1756
1770
  if (encoder.keyMap) {
1757
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1771
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1758
1772
  encode(encoder.encodeKey(key));
1759
1773
  encode(object[key]);
1760
1774
  size++;
1761
1775
  }
1762
1776
  } else {
1763
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1777
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1764
1778
  encode(key);
1765
1779
  encode(object[key]);
1766
1780
  size++;
@@ -1769,7 +1783,7 @@
1769
1783
  target[objectOffset++ + start] = size >> 8;
1770
1784
  target[objectOffset + start] = size & 0xff;
1771
1785
  } :
1772
- (object, safePrototype) => {
1786
+ (object, skipValues) => {
1773
1787
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1774
1788
  let newTransitions = 0;
1775
1789
  let length = 0;
@@ -1788,7 +1802,7 @@
1788
1802
  transition = nextTransition;
1789
1803
  }
1790
1804
  } else {
1791
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1805
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1792
1806
  nextTransition = transition[key];
1793
1807
  if (!nextTransition) {
1794
1808
  if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
@@ -1848,9 +1862,9 @@
1848
1862
  writeArrayHeader(length + 2);
1849
1863
  encode(0xe000 + recordId);
1850
1864
  encode(keys);
1851
- if (safePrototype === null) return; // special exit for iterator
1865
+ if (skipValues) return; // special exit for iterator
1852
1866
  for (let key in object)
1853
- if (safePrototype || object.hasOwnProperty(key))
1867
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
1854
1868
  encode(object[key]);
1855
1869
  return
1856
1870
  }
@@ -1860,9 +1874,9 @@
1860
1874
  } else {
1861
1875
  writeArrayHeader(length);
1862
1876
  }
1863
- if (safePrototype === null) return; // special exit for iterator
1877
+ if (skipValues) return; // special exit for iterator
1864
1878
  for (let key in object)
1865
- if (safePrototype || object.hasOwnProperty(key))
1879
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
1866
1880
  encode(object[key]);
1867
1881
  };
1868
1882
  const makeRoom = (end) => {
@@ -1900,7 +1914,7 @@
1900
1914
  if (constructor === Object) {
1901
1915
  let useRecords = encoder.useRecords !== false;
1902
1916
  if (useRecords)
1903
- writeObject(object, null); // write the record identifier
1917
+ writeObject(object, true); // write the record identifier
1904
1918
  else
1905
1919
  writeEntityLength(Object.keys(object).length, 0xa0);
1906
1920
  for (let key in object) {