fix: listing SSE encrypted multipart objects (#18786)
GetActualSize() was heavily relying on o.Parts() to be non-empty to figure out if the object is multipart or not, However, we have many indicators of whether an object is multipart or not. Blindly assuming that o.Parts == nil is not a multipart, is an incorrect expectation instead, multipart must be obtained via - Stored metadata value indicating this is a multipart encrypted object. - Rely on <meta>-actual-size metadata to get the object's actual size. This value is preserved for additional reasons such as these. - ETag != 32 length
This commit is contained in:
@@ -533,6 +533,14 @@ func (o ObjectInfo) GetActualSize() (int64, error) {
|
||||
return size, nil
|
||||
}
|
||||
if _, ok := crypto.IsEncrypted(o.UserDefined); ok {
|
||||
sizeStr, ok := o.UserDefined[ReservedMetadataPrefix+"actual-size"]
|
||||
if ok {
|
||||
size, err := strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil {
|
||||
return -1, errObjectTampered
|
||||
}
|
||||
return size, nil
|
||||
}
|
||||
return o.DecryptedSize()
|
||||
}
|
||||
|
||||
@@ -632,16 +640,14 @@ func getCompressedOffsets(oi ObjectInfo, offset int64, decrypt func([]byte) ([]b
|
||||
var skipLength int64
|
||||
var cumulativeActualSize int64
|
||||
var firstPartIdx int
|
||||
if len(oi.Parts) > 0 {
|
||||
for i, part := range oi.Parts {
|
||||
cumulativeActualSize += part.ActualSize
|
||||
if cumulativeActualSize <= offset {
|
||||
compressedOffset += part.Size
|
||||
} else {
|
||||
firstPartIdx = i
|
||||
skipLength = cumulativeActualSize - part.ActualSize
|
||||
break
|
||||
}
|
||||
for i, part := range oi.Parts {
|
||||
cumulativeActualSize += part.ActualSize
|
||||
if cumulativeActualSize <= offset {
|
||||
compressedOffset += part.Size
|
||||
} else {
|
||||
firstPartIdx = i
|
||||
skipLength = cumulativeActualSize - part.ActualSize
|
||||
break
|
||||
}
|
||||
}
|
||||
partSkip = offset - skipLength
|
||||
|
||||
Reference in New Issue
Block a user