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/test.js CHANGED
@@ -617,26 +617,45 @@
617
617
  } else if ((byte1 & 0xe0) === 0xc0) {
618
618
  // 2 bytes
619
619
  const byte2 = src[position$1++] & 0x3f;
620
- units.push(((byte1 & 0x1f) << 6) | byte2);
620
+ const codePoint = ((byte1 & 0x1f) << 6) | byte2;
621
+ // Reject overlong encoding: 2-byte sequences must encode values >= 0x80
622
+ if (codePoint < 0x80) {
623
+ units.push(0xFFFD); // replacement character
624
+ } else {
625
+ units.push(codePoint);
626
+ }
621
627
  } else if ((byte1 & 0xf0) === 0xe0) {
622
628
  // 3 bytes
623
629
  const byte2 = src[position$1++] & 0x3f;
624
630
  const byte3 = src[position$1++] & 0x3f;
625
- units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
631
+ const codePoint = ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3;
632
+ // Reject overlong encoding: 3-byte sequences must encode values >= 0x800
633
+ // Also reject surrogates (0xD800-0xDFFF)
634
+ if (codePoint < 0x800 || (codePoint >= 0xD800 && codePoint <= 0xDFFF)) {
635
+ units.push(0xFFFD); // replacement character
636
+ } else {
637
+ units.push(codePoint);
638
+ }
626
639
  } else if ((byte1 & 0xf8) === 0xf0) {
627
640
  // 4 bytes
628
641
  const byte2 = src[position$1++] & 0x3f;
629
642
  const byte3 = src[position$1++] & 0x3f;
630
643
  const byte4 = src[position$1++] & 0x3f;
631
644
  let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
632
- if (unit > 0xffff) {
645
+ // Reject overlong encoding: 4-byte sequences must encode values >= 0x10000
646
+ // Also reject values > 0x10FFFF (maximum valid Unicode)
647
+ if (unit < 0x10000 || unit > 0x10FFFF) {
648
+ units.push(0xFFFD); // replacement character
649
+ } else if (unit > 0xffff) {
633
650
  unit -= 0x10000;
634
651
  units.push(((unit >>> 10) & 0x3ff) | 0xd800);
635
652
  unit = 0xdc00 | (unit & 0x3ff);
653
+ units.push(unit);
654
+ } else {
655
+ units.push(unit);
636
656
  }
637
- units.push(unit);
638
657
  } else {
639
- units.push(byte1);
658
+ units.push(0xFFFD); // replacement character for invalid lead byte
640
659
  }
641
660
 
642
661
  if (units.length >= 0x1000) {
@@ -1338,7 +1357,7 @@
1338
1357
  hasSharedUpdate = false;
1339
1358
  let encodingError;
1340
1359
  try {
1341
- if (packr.randomAccessStructure && value && value.constructor) {
1360
+ if (packr.randomAccessStructure && value && typeof value === 'object') {
1342
1361
  if (value.constructor === Object) writeStruct(value); // simple object
1343
1362
  else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
1344
1363
  // allow user classes, if they don't need special handling (but do use toJSON if available)
@@ -3275,6 +3294,15 @@
3275
3294
  var deserialized = unpack(serialized);
3276
3295
  assert.equal(deserialized, data);
3277
3296
  });
3297
+ test('overlong UTF-8 string', function () {
3298
+ const payload = Buffer.concat([
3299
+ Buffer.from([0xa2]), // msgpack fixstr, 2 bytes
3300
+ Buffer.from([0xc0, 0xaf]), // overlong "/"
3301
+ ]);
3302
+
3303
+ const result = unpack(payload);
3304
+ assert.notEqual(result, '/');
3305
+ });
3278
3306
  test('use ArrayBuffer', function () {
3279
3307
  const data = {prop: 'a test'};
3280
3308
  var serialized = pack(data);