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