fix: reject composite CRC64NVME completion

Remove the remaining type-only canonicalization at CompleteMultipartUpload while preserving legacy uploads stored as FULL_OBJECT.

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-08-29 18:36:02 +08:00
parent 2aea7fe9c4
commit 32b2aa49f1
2 changed files with 7 additions and 10 deletions
+6 -3
View File
@@ -516,7 +516,7 @@ func testAPICompleteMultipartChecksumTypeMismatch(obj ObjectLayer, instanceType,
} }
}) })
t.Run("crc64nvme-composite-remains-canonicalized", func(t *testing.T) { t.Run("crc64nvme-composite-completion-is-rejected", func(t *testing.T) {
crc64Type := hash.ChecksumCRC64NVME crc64Type := hash.ChecksumCRC64NVME
objectName := "type-mismatch/crc64nvme-composite" objectName := "type-mismatch/crc64nvme-composite"
uploadID := newMultipartUploadHTTP(t, apiRouter, credentials, bucketName, objectName, uploadID := newMultipartUploadHTTP(t, apiRouter, credentials, bucketName, objectName,
@@ -527,8 +527,11 @@ func testAPICompleteMultipartChecksumTypeMismatch(obj ObjectLayer, instanceType,
crc64Type.Key(): mustChecksum(t, crc64Type, full), crc64Type.Key(): mustChecksum(t, crc64Type, full),
xhttp.AmzChecksumType: xhttp.AmzChecksumTypeComposite, xhttp.AmzChecksumType: xhttp.AmzChecksumTypeComposite,
}) })
if rec.Code != http.StatusOK { if rec.Code != http.StatusBadRequest || apiErrorCode(t, rec) != "BadDigest" {
t.Fatalf("%s: CRC64NVME canonicalization changed: %d %s", instanceType, rec.Code, rec.Body.String()) t.Fatalf("%s: CRC64NVME composite completion returned %d %s", instanceType, rec.Code, rec.Body.String())
}
if _, err := obj.GetObjectInfo(t.Context(), bucketName, objectName, ObjectOptions{}); err == nil {
t.Fatalf("%s: object was created despite a rejected CRC64NVME checksum type", instanceType)
} }
}) })
} }
+1 -7
View File
@@ -1185,13 +1185,7 @@ func (er erasureObjects) CompleteMultipartUpload(ctx context.Context, bucket str
} }
} }
if opts.wantChecksumType != "" { if opts.wantChecksumType != "" {
providedObjectType := opts.wantChecksumType if opts.wantChecksumType != expectedType.ObjType() {
// CRC64NVME is always canonicalized to FULL_OBJECT. Preserve this
// behavior until its exact AWS wire semantics have been probed.
if checksumType.Base().Is(hash.ChecksumCRC64NVME) {
providedObjectType = xhttp.AmzChecksumTypeFullObject
}
if providedObjectType != expectedType.ObjType() {
return oi, completeMultipartChecksumTypeMismatch(opts.wantChecksumType, expectedType.ObjType()) return oi, completeMultipartChecksumTypeMismatch(opts.wantChecksumType, expectedType.ObjType())
} }
} }