mirror of
https://github.com/pgsty/minio.git
synced 2026-09-19 17:08:28 +03:00
fix: end GetObjectAttributes part pagination correctly
GetObjectAttributes decided truncation by comparing the last returned part number with the part count (cmd/object-handlers.go:720), which is only a coincidence of contiguous numbering. Sparse parts 1/3 reported a complete page as truncated with a marker that loops, and parts 1/3/5 with max-parts=1 stopped after part 3 and silently dropped part 5. Set IsTruncated in the break that proves an eligible part was left unreturned, and zero NextPartNumberMarker when the listing is complete, as ListObjectParts already does. Also reject negative x-amz-max-parts and x-amz-part-number-marker in getAndValidateAttributesOpts with the same API errors ListObjectParts uses, instead of answering an invalid request with an empty parts listing; an absent or zero max-parts still means the default page size. Tests: TestAPIGetObjectAttributesPartsPagination (sparse 1/3/5 and contiguous 1/2 walks on ErasureSD and Erasure), TestGetAndValidateAttributesOptsPartsRange, and the sparse variants of TestAPIGetObjectAttributesMultipartLogicalPartSize. Compatibility: no field is added or removed; IsTruncated and NextPartNumberMarker change only where they were wrong, and negative pagination values that no SDK sends now fail fast. Fixes pgsty/silo#115 Signed-off-by: Feng Ruohang <rh@vonng.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L7qJqWwy8oFA6aCXWRzXQe
This commit is contained in:
@@ -184,6 +184,16 @@ func getAndValidateAttributesOpts(ctx context.Context, w http.ResponseWriter, r
|
||||
return opts, valid
|
||||
}
|
||||
|
||||
// Reject out-of-range page sizes as ListObjectParts does, instead of
|
||||
// answering an invalid request with an empty parts listing.
|
||||
if opts.MaxParts < 0 {
|
||||
apiErr = errorCodes.ToAPIErr(ErrInvalidMaxParts)
|
||||
argumentName = strings.ToLower(xhttp.AmzMaxParts)
|
||||
argumentValue = r.Header.Get(xhttp.AmzMaxParts)
|
||||
valid = false
|
||||
return opts, valid
|
||||
}
|
||||
|
||||
if opts.MaxParts == 0 {
|
||||
opts.MaxParts = maxPartsList
|
||||
}
|
||||
@@ -196,6 +206,14 @@ func getAndValidateAttributesOpts(ctx context.Context, w http.ResponseWriter, r
|
||||
return opts, valid
|
||||
}
|
||||
|
||||
if opts.PartNumberMarker < 0 {
|
||||
apiErr = errorCodes.ToAPIErr(ErrInvalidPartNumberMarker)
|
||||
argumentName = strings.ToLower(xhttp.AmzPartNumberMarker)
|
||||
argumentValue = r.Header.Get(xhttp.AmzPartNumberMarker)
|
||||
valid = false
|
||||
return opts, valid
|
||||
}
|
||||
|
||||
opts.ObjectAttributes = parseObjectAttributes(r.Header)
|
||||
if len(opts.ObjectAttributes) < 1 {
|
||||
apiErr = errorCodes.ToAPIErr(ErrInvalidAttributeName)
|
||||
|
||||
Reference in New Issue
Block a user