msgpackr 1.11.7 → 1.11.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
@@ -621,26 +621,45 @@ function readStringJS(length) {
621
621
  } else if ((byte1 & 0xe0) === 0xc0) {
622
622
  // 2 bytes
623
623
  const byte2 = src[position$1++] & 0x3f;
624
- units.push(((byte1 & 0x1f) << 6) | byte2);
624
+ const codePoint = ((byte1 & 0x1f) << 6) | byte2;
625
+ // Reject overlong encoding: 2-byte sequences must encode values >= 0x80
626
+ if (codePoint < 0x80) {
627
+ units.push(0xFFFD); // replacement character
628
+ } else {
629
+ units.push(codePoint);
630
+ }
625
631
  } else if ((byte1 & 0xf0) === 0xe0) {
626
632
  // 3 bytes
627
633
  const byte2 = src[position$1++] & 0x3f;
628
634
  const byte3 = src[position$1++] & 0x3f;
629
- units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
635
+ const codePoint = ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3;
636
+ // Reject overlong encoding: 3-byte sequences must encode values >= 0x800
637
+ // Also reject surrogates (0xD800-0xDFFF)
638
+ if (codePoint < 0x800 || (codePoint >= 0xD800 && codePoint <= 0xDFFF)) {
639
+ units.push(0xFFFD); // replacement character
640
+ } else {
641
+ units.push(codePoint);
642
+ }
630
643
  } else if ((byte1 & 0xf8) === 0xf0) {
631
644
  // 4 bytes
632
645
  const byte2 = src[position$1++] & 0x3f;
633
646
  const byte3 = src[position$1++] & 0x3f;
634
647
  const byte4 = src[position$1++] & 0x3f;
635
648
  let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
636
- if (unit > 0xffff) {
649
+ // Reject overlong encoding: 4-byte sequences must encode values >= 0x10000
650
+ // Also reject values > 0x10FFFF (maximum valid Unicode)
651
+ if (unit < 0x10000 || unit > 0x10FFFF) {
652
+ units.push(0xFFFD); // replacement character
653
+ } else if (unit > 0xffff) {
637
654
  unit -= 0x10000;
638
655
  units.push(((unit >>> 10) & 0x3ff) | 0xd800);
639
656
  unit = 0xdc00 | (unit & 0x3ff);
657
+ units.push(unit);
658
+ } else {
659
+ units.push(unit);
640
660
  }
641
- units.push(unit);
642
661
  } else {
643
- units.push(byte1);
662
+ units.push(0xFFFD); // replacement character for invalid lead byte
644
663
  }
645
664
 
646
665
  if (units.length >= 0x1000) {
@@ -1343,7 +1362,7 @@ class Packr extends Unpackr {
1343
1362
  hasSharedUpdate = false;
1344
1363
  let encodingError;
1345
1364
  try {
1346
- if (packr.randomAccessStructure && value && value.constructor) {
1365
+ if (packr.randomAccessStructure && value && typeof value === 'object') {
1347
1366
  if (value.constructor === Object) writeStruct(value); // simple object
1348
1367
  else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
1349
1368
  // allow user classes, if they don't need special handling (but do use toJSON if available)