mirror of
https://github.com/rclone/rclone.git
synced 2025-03-09 20:15:14 +08:00
fs/object: fix memory object out of bounds Seek
Some checks failed
build / windows (push) Has been cancelled
build / other_os (push) Has been cancelled
build / mac_amd64 (push) Has been cancelled
build / mac_arm64 (push) Has been cancelled
build / linux (push) Has been cancelled
build / go1.23 (push) Has been cancelled
build / linux_386 (push) Has been cancelled
build / lint (push) Has been cancelled
build / android-all (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/386 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/amd64 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm/v6 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm/v7 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm64 (push) Has been cancelled
Build & Push Docker Images / Merge & Push Final Docker Image (push) Has been cancelled
Some checks failed
build / windows (push) Has been cancelled
build / other_os (push) Has been cancelled
build / mac_amd64 (push) Has been cancelled
build / mac_arm64 (push) Has been cancelled
build / linux (push) Has been cancelled
build / go1.23 (push) Has been cancelled
build / linux_386 (push) Has been cancelled
build / lint (push) Has been cancelled
build / android-all (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/386 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/amd64 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm/v6 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm/v7 (push) Has been cancelled
Build & Push Docker Images / Build Docker Image for linux/arm64 (push) Has been cancelled
Build & Push Docker Images / Merge & Push Final Docker Image (push) Has been cancelled
This commit is contained in:
parent
64b3d1d539
commit
ccef29bbff
@ -279,19 +279,26 @@ func (o *MemoryObject) SetModTime(ctx context.Context, modTime time.Time) error
|
||||
|
||||
// Open opens the file for read. Call Close() on the returned io.ReadCloser
|
||||
func (o *MemoryObject) Open(ctx context.Context, options ...fs.OpenOption) (io.ReadCloser, error) {
|
||||
content := o.content
|
||||
var offset, limit int64 = 0, -1
|
||||
for _, option := range options {
|
||||
switch x := option.(type) {
|
||||
case *fs.RangeOption:
|
||||
content = o.content[x.Start:x.End]
|
||||
offset, limit = x.Decode(o.Size())
|
||||
case *fs.SeekOption:
|
||||
content = o.content[x.Offset:]
|
||||
offset = x.Offset
|
||||
default:
|
||||
if option.Mandatory() {
|
||||
fs.Logf(o, "Unsupported mandatory option: %v", option)
|
||||
}
|
||||
}
|
||||
}
|
||||
content := o.content
|
||||
offset = max(offset, 0)
|
||||
if limit < 0 {
|
||||
content = content[offset:]
|
||||
} else {
|
||||
content = content[offset:min(offset+limit, int64(len(content)))]
|
||||
}
|
||||
return io.NopCloser(bytes.NewBuffer(content)), nil
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,7 @@ func TestMemoryObject(t *testing.T) {
|
||||
assert.Equal(t, newNow, o.ModTime(context.Background()))
|
||||
|
||||
checkOpen := func(rc io.ReadCloser, expected string) {
|
||||
t.Helper()
|
||||
actual, err := io.ReadAll(rc)
|
||||
assert.NoError(t, err)
|
||||
err = rc.Close()
|
||||
@ -118,6 +119,7 @@ func TestMemoryObject(t *testing.T) {
|
||||
}
|
||||
|
||||
checkContent := func(o fs.Object, expected string) {
|
||||
t.Helper()
|
||||
rc, err := o.Open(context.Background())
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, expected)
|
||||
@ -127,12 +129,28 @@ func TestMemoryObject(t *testing.T) {
|
||||
|
||||
rc, err := o.Open(context.Background(), &fs.RangeOption{Start: 1, End: 3})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "ot")
|
||||
checkOpen(rc, "ota")
|
||||
|
||||
rc, err = o.Open(context.Background(), &fs.RangeOption{Start: 1, End: -1})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "otato")
|
||||
|
||||
rc, err = o.Open(context.Background(), &fs.RangeOption{Start: 1, End: 4096})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "otato")
|
||||
|
||||
rc, err = o.Open(context.Background(), &fs.RangeOption{Start: -1, End: 4})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "tato")
|
||||
|
||||
rc, err = o.Open(context.Background(), &fs.SeekOption{Offset: 3})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "ato")
|
||||
|
||||
rc, err = o.Open(context.Background(), &fs.SeekOption{Offset: -100})
|
||||
assert.NoError(t, err)
|
||||
checkOpen(rc, "potato")
|
||||
|
||||
// check it fits within the buffer
|
||||
newNow = now.Add(2 * time.Minute)
|
||||
newContent := bytes.NewBufferString("Rutabaga")
|
||||
|
Loading…
x
Reference in New Issue
Block a user