mirror of
https://github.com/pgsty/minio.git
synced 2026-08-09 15:53:28 +03:00
fix: reject duplicate part numbers in CompleteMultipartUpload
sort.SliceIsSorted with a strict '<' predicate treats equal neighbours as sorted, so a completion list like [1,1] passed the order check and the same part was assembled into the object twice: a single uploaded 5 MiB part produced a 10 MiB object. Replace the check with an explicit strictly-increasing scan that rejects repeats with InvalidPartOrder before anything is assembled. Gaps and lists not starting at part 1 remain legal, matching AWS semantics. The regression test drives the real CompleteMultipartUpload handler on both Erasure backends and asserts that rejected completions leave no object behind and keep the upload retryable. Closes #49 Co-authored-by: ChatGPT <noreply@openai.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,6 @@ import (
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -967,11 +966,15 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
||||
return
|
||||
}
|
||||
|
||||
if !sort.SliceIsSorted(complMultipartUpload.Parts, func(i, j int) bool {
|
||||
return complMultipartUpload.Parts[i].PartNumber < complMultipartUpload.Parts[j].PartNumber
|
||||
}) {
|
||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPartOrder), r.URL)
|
||||
return
|
||||
// The parts list must be strictly increasing by part number. Gaps are
|
||||
// allowed, repeats are not - sort.SliceIsSorted() with a '<' predicate
|
||||
// considers equal neighbours sorted, so it is checked explicitly here,
|
||||
// before anything is assembled into the target object.
|
||||
for i := 1; i < len(complMultipartUpload.Parts); i++ {
|
||||
if complMultipartUpload.Parts[i-1].PartNumber >= complMultipartUpload.Parts[i].PartNumber {
|
||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPartOrder), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Reject retention or governance headers if set, CompleteMultipartUpload spec
|
||||
|
||||
Reference in New Issue
Block a user