Appending an empty buffer corrupts subsequent positional reads

Đang mở
#12 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
76/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
node.js, typescript
Lĩnh vực
backend

Hướng nghiên cứu

Start at DynamicBuffer.append(), prepend(), appendFrom(), and prependFrom(), then reproduce the empty-chunk case with positional reads at every offset. Add a regression test that interleaves empty and non-empty buffers and verifies each read, including multi-byte reads; done means empty buffers no longer shift or corrupt positional results.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Summary

Appending a zero-length buffer inserts an empty chunk that corrupts every subsequent positional read. length, slice() and subarray() stay correct, so the buffer looks fine until something reads it by offset.

Reproduced on @platformatic/dynamic-buffer@0.3.1, Node.js v24.18.0.

Reproduction

import { DynamicBuffer } from '@platformatic/dynamic-buffer'

const b = new DynamicBuffer()
b.append(Buffer.from([1, 2]))
b.append(Buffer.alloc(0))   // <-- empty chunk
b.append(Buffer.from([3, 4]))

b.length                    // 4          correct
b.slice(0).toString('hex')  // '01020304' correct

b.readInt8(2)               // 0          expected 3
b.readInt8(3)               // 4          correct
b.readInt16BE(1)            // 512        expected 515
b.readInt32BE(0)            // 16908288   expected 16909060

Without the Buffer.alloc(0) line, readInt8(0..3) returns 1,2,3,4 as expected.

The pattern of the failure — index 2 reads as 0, index 3 is fine — suggests the offset-to-chunk resolution counts the empty chunk as occupying a position, so one byte is skipped and reads as zero. Multi-byte reads spanning the boundary inherit the same error.

Impact

@platformatic/kafka serializes Kafka protocol frames through DynamicBuffer, and several protocol fields are legitimately empty without being null — empty (non-null) record keys and values, empty BYTES/COMPACT_BYTES fields. Writer.appendString, Writer.appendBytes and Writer.appendVarIntBytes all have to guard their appends with if (value.length > 0) to avoid this, which is easy to forget on the next call site added.

Nothing is corrupt on the wire today, because the write path drains via slice()/subarray() and crc32c() reads the flattened .buffer. The hazard is on anything that reads a DynamicBuffer positionally, which is what Reader does.

Suggested fix

Skip zero-length buffers in append()/prepend() (and appendFrom/prependFrom) rather than pushing an empty chunk, so callers do not each have to guard. Alternatively fix the offset-to-chunk resolution to tolerate empty chunks.

Either way it would be worth a regression test that interleaves empty and non-empty appends and then reads every offset back.

Ngôn ngữ chính
TypeScript
Star
17
Fork
2
Merge trung bình
26 phút
Pull request đã merge (30 ngày)
1

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.