Make isIndexedMetaV2 return errors (#15012)

Indexed streams would be decoded by the legacy loader if there 
was an error loading it. Return an error when the stream is indexed 
and it cannot be loaded.

Fixes "unknown minor metadata version" on corrupted xl.meta files and 
returns an actual error.
This commit is contained in:
Klaus Post
2022-05-31 19:06:57 -07:00
committed by GitHub
parent 7b2198f7e5
commit f7cecf0945
4 changed files with 23 additions and 17 deletions

View File

@@ -793,34 +793,32 @@ func decodeVersions(buf []byte, versions int, fn func(idx int, hdr, meta []byte)
}
// isIndexedMetaV2 returns non-nil result if metadata is indexed.
// If data doesn't validate nil is also returned.
func isIndexedMetaV2(buf []byte) (meta xlMetaBuf, data xlMetaInlineData) {
// Returns 3x nil if not XLV2 or not indexed.
// If indexed and unable to parse an error will be returned.
func isIndexedMetaV2(buf []byte) (meta xlMetaBuf, data xlMetaInlineData, err error) {
buf, major, minor, err := checkXL2V1(buf)
if err != nil {
return nil, nil
}
if major != 1 || minor < 3 {
return nil, nil
if err != nil || major != 1 || minor < 3 {
return nil, nil, nil
}
meta, buf, err = msgp.ReadBytesZC(buf)
if err != nil {
return nil, nil
return nil, nil, err
}
if crc, nbuf, err := msgp.ReadUint32Bytes(buf); err == nil {
// Read metadata CRC
buf = nbuf
if got := uint32(xxhash.Sum64(meta)); got != crc {
return nil, nil
return nil, nil, fmt.Errorf("xlMetaV2.Load version(%d), CRC mismatch, want 0x%x, got 0x%x", minor, crc, got)
}
} else {
return nil, nil
return nil, nil, err
}
data = buf
if data.validate() != nil {
data.repair()
}
return meta, data
return meta, data, nil
}
type xlMetaV2ShallowVersion struct {
@@ -865,7 +863,9 @@ func (x *xlMetaV2) LoadOrConvert(buf []byte) error {
// Load all versions of the stored data.
// Note that references to the incoming buffer will be kept.
func (x *xlMetaV2) Load(buf []byte) error {
if meta, data := isIndexedMetaV2(buf); meta != nil {
if meta, data, err := isIndexedMetaV2(buf); err != nil {
return err
} else if meta != nil {
return x.loadIndexed(meta, data)
}
// Convert older format.