diff --git a/roaring/roaring.go b/roaring/roaring.go index 1dcf5e7cb..7b1d24666 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -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)). diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 3ee835d8a..7d35779ce 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -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) }