extra protection of bitmapToArray

This commit is contained in:
Todd Gruben 2022-03-10 07:48:51 -06:00
parent 4a6c0ab086
commit 09a9932951
2 changed files with 38 additions and 11 deletions

View file

@ -176,6 +176,14 @@ func TestSliceContainers(t *testing.T) {
})
}
func TestContainersFB1247(t *testing.T) {
bm := [bitmapN]uint64{0xF}
co := NewContainerBitmap(1, bm[:])
co = co.bitmapToArray()
//should not panic
}
func genRun(r *rand.Rand) Interval16 {
gen:
dat := r.Uint32()

View file

@ -3567,21 +3567,40 @@ func (c *Container) bitmapToArray() *Container {
return c
}
bitmap := c.bitmap()
n := int32(0)
array := make([]uint16, c.N())
for i, word := range bitmap {
for word != 0 {
t := word & -word
if roaringParanoia {
if n >= c.N() {
panic("bitmap has more bits set than container.n")
// FB-1247 adding an extra check just in case c.N proves to be unreliable
// TODO prove this has to be reliable
makeArray := func(bm []uint64, ar []uint16) ([]uint16, bool, int32) {
n := int32(0)
for i, word := range bm {
for word != 0 {
t := word & -word
if roaringParanoia {
if n >= c.N() {
panic("bitmap has more bits set than container.n")
}
}
if n == int32(len(ar)) {
return ar, true, n
}
ar[n] = uint16((i*64 + int(popcount(t-1))))
n++
word ^= t
}
array[n] = uint16((i*64 + int(popcount(t-1))))
n++
word ^= t
}
return ar, false, n
}
array, fail, n := makeArray(bitmap, make([]uint16, c.N()))
if fail {
// the onlyreason we are here is because N was incorrect
// so we force a recount of N and try again
c.bitmapRepair() // the onlyreason we are here is because N was incorrect
array, fail, n = makeArray(bitmap, make([]uint16, c.N()))
if fail {
//this should not be able to happen under any circumstance
panic("bitmapToArray failure")
}
}
if roaringParanoia {
if n != c.N() {