Fix cookie order and check storage version on read

This commit is contained in:
Alan Bernstein 2017-06-15 17:51:28 -05:00 committed by Matt Jaffee
parent d068f53d93
commit fee3996351
2 changed files with 36 additions and 13 deletions

View file

@ -35,8 +35,8 @@ const (
// cookie is the first four bytes in a roaring bitmap file,
// formed by joining magicNumber and storageVersion
cookieNoRuns = magicNumberNoRuns<<16 + storageVersion
cookie = magicNumber<<16 + storageVersion
cookieNoRuns = magicNumberNoRuns + storageVersion<<16
cookie = magicNumber + storageVersion<<16
// headerBaseSize is the size of the cookie and key count at the beginning of a file.
// Headers in files with runs also include runFlagBitset, of length (numContainers+7)/8.
@ -630,15 +630,20 @@ func (b *Bitmap) UnmarshalBinary(data []byte) error {
return errors.New("data too small")
}
// Verify the first sizeof(cookie)=4 bytes are a valid cookie.
v := binary.LittleEndian.Uint32(data[0:4])
// Verify the first two bytes are a valid magicNumber, and second two bytes match current storageVersion.
fileMagic := uint32(binary.LittleEndian.Uint16(data[0:2]))
fileVersion := uint32(binary.LittleEndian.Uint16(data[2:4]))
containsRuns := false
if v == cookieNoRuns {
if fileMagic == magicNumberNoRuns {
// noop
} else if v == cookie {
} else if fileMagic == magicNumber {
containsRuns = true
} else {
return errors.New("invalid roaring file")
return fmt.Errorf("invalid roaring file, magic number %v is incorrect", fileMagic)
}
if fileVersion != storageVersion {
return fmt.Errorf("wrong roaring version, file is v%d, server requires v%d", fileVersion, storageVersion)
}
// Read key count in bytes sizeof(cookie):(sizeof(cookie)+sizeof(uint32)).

View file

@ -1341,8 +1341,14 @@ func TestWriteReadArray(t *testing.T) {
ba := &Bitmap{keys: []uint64{0}, containers: []*container{ca}}
ba2 := &Bitmap{}
var buf bytes.Buffer
ba.WriteTo(&buf)
ba2.UnmarshalBinary(buf.Bytes())
_, err := ba.WriteTo(&buf)
if err != nil {
t.Fatalf("error writing: %v", err)
}
err = ba2.UnmarshalBinary(buf.Bytes())
if err != nil {
t.Fatalf("error unmarshaling: %v", err)
}
if !reflect.DeepEqual(ba2.containers[0].array, ca.array) {
t.Fatalf("array test expected %x, but got %x", ca.array, ba2.containers[0].array)
}
@ -1357,8 +1363,14 @@ func TestWriteReadBitmap(t *testing.T) {
bb := &Bitmap{keys: []uint64{0}, containers: []*container{cb}}
bb2 := &Bitmap{}
var buf bytes.Buffer
bb.WriteTo(&buf)
bb2.UnmarshalBinary(buf.Bytes())
_, err := bb.WriteTo(&buf)
if err != nil {
t.Fatalf("error writing: %v", err)
}
err = bb2.UnmarshalBinary(buf.Bytes())
if err != nil {
t.Fatalf("error unmarshaling: %v", err)
}
if !reflect.DeepEqual(bb2.containers[0].bitmap, cb.bitmap) {
t.Fatalf("bitmap test expected %x, but got %x", cb.bitmap, bb2.containers[0].bitmap)
}
@ -1369,8 +1381,14 @@ func TestWriteReadRun(t *testing.T) {
br := &Bitmap{keys: []uint64{0}, containers: []*container{cr}}
br2 := &Bitmap{}
var buf bytes.Buffer
br.WriteTo(&buf)
br2.UnmarshalBinary(buf.Bytes())
_, err := br.WriteTo(&buf)
if err != nil {
t.Fatalf("error writing: %v", err)
}
err = br2.UnmarshalBinary(buf.Bytes())
if err != nil {
t.Fatalf("error unmarshaling: %v", err)
}
if !reflect.DeepEqual(br2.containers[0].runs, cr.runs) {
t.Fatalf("run test expected %x, but got %x", cr.runs, br2.containers[0].runs)
}