Describe the bug(Bug 描述)
DefaultOneHitBloomFilter and NewOneHitBloomFilter panic with slice bounds out of range when the buffer size is too small for the hash values provided. There is no input validation or documentation of minimum size requirements.
Reproduction
func TestBloomFilter_PanicOnSmallSize(t *testing.T) {
bf := bloomfilter.DefaultOneHitBloomFilter(0, 8)
hash := uint64(0x2000000000000)
bf.Add(hash) // panic: slice bounds out of range [:9] with capacity 8
}
All three versions (V0, V2, V3) are affected:
// V0: offset = hash >> 49, max offset = 32767, min size = 32775
bf := bloomfilter.DefaultOneHitBloomFilter(0, 8)
bf.Add(uint64(0x2000000000000)) // panic
// V2: offset = hash >> 46, max offset = 262143, min size = 262151
bf := bloomfilter.DefaultOneHitBloomFilter(2, 8)
bf.Add(uint64(0x400000000000)) // panic
// V3: offset = hash >> 46, max offset = 262143, min size = 262151
bf := bloomfilter.DefaultOneHitBloomFilter(3, 8)
bf.Add(uint64(0x400000000000)) // panic
Even a single byte below the minimum causes a panic:
bf := bloomfilter.DefaultOneHitBloomFilter(0, 32774) // min is 32775
bf.Add(uint64(0x7FFF)<<49) // panic: slice bounds out of range [:32775] with capacity 32774
Root Cause
The Add() and Hit() methods compute offsets from hash values without bounds checking:
// bloomfilter.go:89-94
func (b *OneHitBloomFilterV0) Add(hash uint64) {
var offset = int(hash >> 49) // offset can be 0..32767
// ...
s := binary.LittleEndian.Uint64(b.bytes[offset : offset+8]) // panic if offset+8 > len(b.bytes)
}
| Version |
Offset Calculation |
Max Offset |
Min Required Size |
| V0/V1 |
hash >> 49 |
32,767 |
32,775 bytes |
| V2/V3 |
hash >> 46 |
262,143 |
262,151 bytes |
Production Status
Production code is not currently affected because it always uses the correct sizes from constants:
// lib/logstore/constant.go
LogStoreConstantV0 = InitConstant(32*1024+64, ...) // 32,832 bytes (57 byte margin)
LogStoreConstantV2 = InitConstant(256*1024+64, ...) // 262,208 bytes (57 byte margin)
However, nothing prevents future code from passing an invalid size. The API accepts any int64 with no validation or documentation.
Suggested Fix
Add minimum size validation:
func DefaultOneHitBloomFilter(version uint32, bloomfiterSize int64) Bloomfilter {
minSize := int64(32775) // version <= 1
if version >= 2 {
minSize = 262151
}
if bloomfiterSize < minSize {
panic(fmt.Sprintf("bloomfilter version %d requires at least %d bytes, got %d",
version, minSize, bloomfiterSize))
}
bytes := make([]byte, bloomfiterSize)
return NewOneHitBloomFilter(bytes, version)
}
To Reproduce(Bug 复现步骤)
No response
Expected behavior(期望结果)
No response
Screenshots(屏幕截图)
No response
Logs(完整的错误日志)
No response
Additional context(其他的一些补充内容)
No response
Describe the bug(Bug 描述)
DefaultOneHitBloomFilterandNewOneHitBloomFilterpanic withslice bounds out of rangewhen the buffer size is too small for the hash values provided. There is no input validation or documentation of minimum size requirements.Reproduction
All three versions (V0, V2, V3) are affected:
Even a single byte below the minimum causes a panic:
Root Cause
The
Add()andHit()methods compute offsets from hash values without bounds checking:hash >> 49hash >> 46Production Status
Production code is not currently affected because it always uses the correct sizes from constants:
However, nothing prevents future code from passing an invalid size. The API accepts any
int64with no validation or documentation.Suggested Fix
Add minimum size validation:
To Reproduce(Bug 复现步骤)
No response
Expected behavior(期望结果)
No response
Screenshots(屏幕截图)
No response
Logs(完整的错误日志)
No response
Additional context(其他的一些补充内容)
No response