cbor-x 1.5.7 → 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.
package/dist/node.cjs CHANGED
@@ -501,7 +501,12 @@ function createStructureReader(structure) {
501
501
  }
502
502
 
503
503
  function safeKey(key) {
504
- return key === '__proto__' ? '__proto_' : key
504
+ // protect against prototype pollution
505
+ if (typeof key === 'string') return key === '__proto__' ? '__proto_' : key
506
+ if (typeof key === 'number' || typeof key === 'boolean' || typeof key === 'bigint') return key.toString();
507
+ if (key == null) return key + '';
508
+ // protect against expensive (DoS) string conversions
509
+ throw new Error('Invalid property name type ' + typeof key);
505
510
  }
506
511
 
507
512
  let readFixedString = readStringJS;
@@ -919,6 +924,7 @@ currentExtensions[28] = (read) => {
919
924
  referenceMap.id = 0;
920
925
  }
921
926
  let id = referenceMap.id++;
927
+ let startingPosition = position$1;
922
928
  let token = src[position$1];
923
929
  let target;
924
930
  // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
@@ -931,8 +937,20 @@ currentExtensions[28] = (read) => {
931
937
  let refEntry = { target }; // a placeholder object
932
938
  referenceMap.set(id, refEntry);
933
939
  let targetProperties = read(); // read the next value as the target object to id
934
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
940
+ if (refEntry.used) {// there is a cycle, so we have to assign properties to original target
941
+ if (Object.getPrototypeOf(target) !== Object.getPrototypeOf(targetProperties)) {
942
+ // this means that the returned target does not match the targetProperties, so we need rerun the read to
943
+ // have the correctly create instance be assigned as a reference, then we do the copy the properties back to the
944
+ // target
945
+ // reset the position so that the read can be repeated
946
+ position$1 = startingPosition;
947
+ // the returned instance is our new target for references
948
+ target = targetProperties;
949
+ referenceMap.set(id, { target });
950
+ targetProperties = read();
951
+ }
935
952
  return Object.assign(target, targetProperties)
953
+ }
936
954
  refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
937
955
  return targetProperties // no cycle, can just use the returned read object
938
956
  };
@@ -1014,7 +1032,7 @@ function registerTypedArray(TypedArray, tag) {
1014
1032
  for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
1015
1033
  if (!littleEndian && bytesPerElement == 1)
1016
1034
  continue
1017
- let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
1035
+ let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : bytesPerElement == 8 ? 3 : 0;
1018
1036
  currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine$1) ? (buffer) => {
1019
1037
  if (!TypedArray)
1020
1038
  throw new Error('Could not find typed array for code ' + tag)
@@ -1024,7 +1042,7 @@ function registerTypedArray(TypedArray, tag) {
1024
1042
  bytesPerElement === 2 && !(buffer.byteOffset & 1) ||
1025
1043
  bytesPerElement === 4 && !(buffer.byteOffset & 3) ||
1026
1044
  bytesPerElement === 8 && !(buffer.byteOffset & 7))
1027
- return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
1045
+ return new TypedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength >> sizeShift);
1028
1046
  }
1029
1047
  // we have to slice/copy here to get a new ArrayBuffer, if we are not word/byte aligned
1030
1048
  return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
@@ -1628,7 +1646,7 @@ class Encoder extends Decoder {
1628
1646
  }
1629
1647
  let constructor = value.constructor;
1630
1648
  if (constructor === Object) {
1631
- writeObject(value, true);
1649
+ writeObject(value);
1632
1650
  } else if (constructor === Array) {
1633
1651
  length = value.length;
1634
1652
  if (length < 0x18) {
@@ -1723,8 +1741,8 @@ class Encoder extends Decoder {
1723
1741
  return encode(json)
1724
1742
  }
1725
1743
 
1726
- // no extension found, write as object
1727
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1744
+ // no extension found, write as a plain object
1745
+ writeObject(value);
1728
1746
  }
1729
1747
  }
1730
1748
  } else if (type === 'boolean') {
@@ -1786,19 +1804,19 @@ class Encoder extends Decoder {
1786
1804
  }
1787
1805
  }
1788
1806
  } :
1789
- (object, safePrototype) => {
1807
+ (object) => {
1790
1808
  target[position++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1791
1809
  let objectOffset = position - start;
1792
1810
  position += 2;
1793
1811
  let size = 0;
1794
1812
  if (encoder.keyMap) {
1795
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1813
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1796
1814
  encode(encoder.encodeKey(key));
1797
1815
  encode(object[key]);
1798
1816
  size++;
1799
1817
  }
1800
1818
  } else {
1801
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1819
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1802
1820
  encode(key);
1803
1821
  encode(object[key]);
1804
1822
  size++;
@@ -1807,7 +1825,7 @@ class Encoder extends Decoder {
1807
1825
  target[objectOffset++ + start] = size >> 8;
1808
1826
  target[objectOffset + start] = size & 0xff;
1809
1827
  } :
1810
- (object, safePrototype) => {
1828
+ (object, skipValues) => {
1811
1829
  let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1812
1830
  let newTransitions = 0;
1813
1831
  let length = 0;
@@ -1826,7 +1844,7 @@ class Encoder extends Decoder {
1826
1844
  transition = nextTransition;
1827
1845
  }
1828
1846
  } else {
1829
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1847
+ for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
1830
1848
  nextTransition = transition[key];
1831
1849
  if (!nextTransition) {
1832
1850
  if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
@@ -1886,9 +1904,9 @@ class Encoder extends Decoder {
1886
1904
  writeArrayHeader(length + 2);
1887
1905
  encode(0xe000 + recordId);
1888
1906
  encode(keys);
1889
- if (safePrototype === null) return; // special exit for iterator
1907
+ if (skipValues) return; // special exit for iterator
1890
1908
  for (let key in object)
1891
- if (safePrototype || object.hasOwnProperty(key))
1909
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
1892
1910
  encode(object[key]);
1893
1911
  return
1894
1912
  }
@@ -1898,9 +1916,9 @@ class Encoder extends Decoder {
1898
1916
  } else {
1899
1917
  writeArrayHeader(length);
1900
1918
  }
1901
- if (safePrototype === null) return; // special exit for iterator
1919
+ if (skipValues) return; // special exit for iterator
1902
1920
  for (let key in object)
1903
- if (safePrototype || object.hasOwnProperty(key))
1921
+ if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key))
1904
1922
  encode(object[key]);
1905
1923
  };
1906
1924
  const makeRoom = (end) => {
@@ -1938,7 +1956,7 @@ class Encoder extends Decoder {
1938
1956
  if (constructor === Object) {
1939
1957
  let useRecords = encoder.useRecords !== false;
1940
1958
  if (useRecords)
1941
- writeObject(object, null); // write the record identifier
1959
+ writeObject(object, true); // write the record identifier
1942
1960
  else
1943
1961
  writeEntityLength(Object.keys(object).length, 0xa0);
1944
1962
  for (let key in object) {