fs: fix negative offset when a suffix Range request exceeds object size
A Range header requesting a suffix longer than the object (e.g. "bytes=-90407" against a 5 byte object) caused RangeOption.Decode to compute a negative offset (size - End), which serve.Object then used directly as a slice/seek offset and panicked with "slice bounds out of range". FixRangeOption (used by backends like OneDrive/Box that lack native suffix-range support) had the same root cause: it produced a RangeOption with a negative Start, which Header() silently dropped, turning the request into the wrong byte range instead of erroring or serving the whole object. Per RFC 7233 section 2.1, when the suffix-length exceeds the representation size, the entire representation should be served. Clamp the computed offset/start to 0 in both places. Fixes #6310
This commit is contained in:
committed by
Nick Craig-Wood
parent
b12251f07f
commit
cb41e42d04
+14
-1
@@ -126,6 +126,12 @@ func (o *RangeOption) Decode(size int64) (offset, limit int64) {
|
||||
} else {
|
||||
if o.End >= 0 {
|
||||
offset = size - o.End
|
||||
if offset < 0 {
|
||||
// RFC 7233 section 2.1: if the suffix-length is
|
||||
// larger than the representation, use the entire
|
||||
// representation.
|
||||
offset = 0
|
||||
}
|
||||
} else {
|
||||
offset = 0
|
||||
}
|
||||
@@ -162,7 +168,14 @@ func FixRangeOption(options []OpenOption, size int64) {
|
||||
case *RangeOption:
|
||||
// If start is < 0 then fetch from the end
|
||||
if x.Start < 0 {
|
||||
x = &RangeOption{Start: size - x.End, End: -1}
|
||||
start := size - x.End
|
||||
if start < 0 {
|
||||
// RFC 7233 section 2.1: if the suffix-length is
|
||||
// larger than the representation, use the entire
|
||||
// representation (#6310).
|
||||
start = 0
|
||||
}
|
||||
x = &RangeOption{Start: start, End: -1}
|
||||
options[i] = x
|
||||
}
|
||||
// If end is too big or undefined, fetch to the end
|
||||
|
||||
Reference in New Issue
Block a user