@naeemo/capnp 0.9.0 → 0.9.1

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/index.js CHANGED
@@ -550,21 +550,38 @@ var ListBuilder = class {
550
550
  * Cap'n Proto MessageReader
551
551
  * 纯 TypeScript 实现
552
552
  */
553
+ /** 默认安全选项 */
554
+ const DEFAULT_SECURITY_OPTIONS = {
555
+ maxSegments: 64,
556
+ maxTotalSize: 64 * 1024 * 1024,
557
+ strictMode: false
558
+ };
553
559
  var MessageReader = class {
554
560
  segments;
555
- constructor(buffer) {
561
+ securityOptions;
562
+ constructor(buffer, securityOptions) {
563
+ this.securityOptions = {
564
+ ...DEFAULT_SECURITY_OPTIONS,
565
+ ...securityOptions
566
+ };
556
567
  const uint8Array = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;
557
568
  this.segments = [];
569
+ if (this.securityOptions.strictMode && uint8Array.byteLength > this.securityOptions.maxTotalSize) throw new Error(`Message size (${uint8Array.byteLength} bytes) exceeds maximum allowed size (${this.securityOptions.maxTotalSize} bytes)`);
558
570
  if (uint8Array.byteLength < 8) return;
559
571
  const view = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);
560
572
  const firstWordLow = view.getUint32(0, true);
561
573
  const firstWordHigh = view.getUint32(4, true);
562
574
  const segmentCount = (firstWordLow & 4294967295) + 1;
563
575
  const firstSegmentSize = firstWordHigh;
576
+ if (segmentCount > this.securityOptions.maxSegments) {
577
+ if (this.securityOptions.strictMode) throw new Error(`Segment count (${segmentCount}) exceeds maximum allowed (${this.securityOptions.maxSegments})`);
578
+ return;
579
+ }
564
580
  let offset = 8;
565
581
  const segmentSizes = [firstSegmentSize];
566
582
  for (let i = 1; i < segmentCount; i++) {
567
583
  if (offset + 4 > uint8Array.byteLength) {
584
+ if (this.securityOptions.strictMode) throw new Error(`Message ended prematurely while reading segment ${i} size (offset: ${offset}, length: ${uint8Array.byteLength})`);
568
585
  this.segments = [];
569
586
  return;
570
587
  }
@@ -573,12 +590,24 @@ var MessageReader = class {
573
590
  }
574
591
  offset = offset + 7 & -8;
575
592
  if (offset > uint8Array.byteLength) {
593
+ if (this.securityOptions.strictMode) throw new Error(`Insufficient data for segment table (offset: ${offset}, length: ${uint8Array.byteLength})`);
576
594
  this.segments = [];
577
595
  return;
578
596
  }
597
+ const headerSize = offset;
598
+ let totalBodySize = 0;
599
+ for (const size of segmentSizes) totalBodySize += size * WORD_SIZE;
600
+ const expectedTotalSize = headerSize + totalBodySize;
601
+ if (expectedTotalSize > this.securityOptions.maxTotalSize) {
602
+ if (this.securityOptions.strictMode) throw new Error(`Total message size (${expectedTotalSize} bytes) exceeds maximum allowed size (${this.securityOptions.maxTotalSize} bytes)`);
603
+ return;
604
+ }
579
605
  this.segments = [];
580
606
  for (const size of segmentSizes) {
581
- if (offset + size * WORD_SIZE > uint8Array.byteLength) break;
607
+ if (offset + size * WORD_SIZE > uint8Array.byteLength) {
608
+ if (this.securityOptions.strictMode) throw new Error(`Insufficient data for segment (expected ${size * WORD_SIZE} bytes at offset ${offset}, but message is ${uint8Array.byteLength} bytes)`);
609
+ break;
610
+ }
582
611
  const segmentBuffer = uint8Array.slice(offset, offset + size * WORD_SIZE);
583
612
  this.segments.push(Segment.fromBuffer(segmentBuffer.buffer));
584
613
  offset += size * WORD_SIZE;
@@ -672,6 +701,12 @@ var MessageReader = class {
672
701
  get segmentCount() {
673
702
  return this.segments.length;
674
703
  }
704
+ /**
705
+ * 获取当前安全选项配置
706
+ */
707
+ getSecurityOptions() {
708
+ return { ...this.securityOptions };
709
+ }
675
710
  };
676
711
  /**
677
712
  * 结构读取器