Skip to content

Commit

Permalink
chunked: fix divide by zero in bloom filter
Browse files Browse the repository at this point in the history
if the bloom filter size is zero, the "% size" operation fails with a
divide by zero.

Closes: #1903

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Apr 23, 2024
1 parent 8b0c90d commit 5410d8c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
5 changes: 4 additions & 1 deletion pkg/chunked/bloom_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ type bloomFilter struct {

func newBloomFilter(size int, k uint32) *bloomFilter {
numElements := (size + 63) / 64
if numElements == 0 {
numElements = 1
}
return &bloomFilter{
bitArray: make([]uint64, numElements),
k: k,
Expand All @@ -28,7 +31,7 @@ func newBloomFilterFromArray(bitArray []uint64, k uint32) *bloomFilter {

func (bf *bloomFilter) hashFn(item []byte, seed uint32) (uint64, uint64) {
if len(item) == 0 {
return 0, 0
return 0, 1
}
mod := uint32(len(bf.bitArray) * 64)
seedSplit := seed % uint32(len(item))
Expand Down
25 changes: 25 additions & 0 deletions pkg/chunked/bloom_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package chunked
import (
"bytes"
"io"
"math/bits"
"testing"

digest "github.com/opencontainers/go-digest"
Expand Down Expand Up @@ -125,3 +126,27 @@ func TestBloomFilter(t *testing.T) {
assert.True(t, contains)
}
}

func TestStressBloomHashFn(t *testing.T) {
data := []byte("sha256:2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9")
for numberHashes := uint32(1); numberHashes <= 3; numberHashes++ {
for size := 0; size < (1 << 16); size = size<<1 + 1 {
bloomFilter := newBloomFilter(size, numberHashes)
for seed := uint32(0); seed < numberHashes; seed++ {
index, mask := bloomFilter.hashFn([]byte{}, seed)
assert.True(t, int(index) < len(bloomFilter.bitArray))
assert.Equal(t, bits.OnesCount64(mask), 1)

index, mask = bloomFilter.hashFn(data, seed)
assert.True(t, int(index) < len(bloomFilter.bitArray))
assert.Equal(t, bits.OnesCount64(mask), 1)

index, mask = bloomFilter.hashFn(data[:len(data)/2], seed)
assert.True(t, int(index) < len(bloomFilter.bitArray))
assert.Equal(t, bits.OnesCount64(mask), 1)

}
}
}

}

0 comments on commit 5410d8c

Please sign in to comment.