From 64b5a76bec1a49cf74355f8bc939988649424b91 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 5 Nov 2016 09:59:36 +0000 Subject: [PATCH] mount: detect and deal with seeking beyond end of file - fixes #828 --- cmd/mount/fs.go | 1 + cmd/mount/read.go | 8 ++++++++ cmd/mount/read_test.go | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/cmd/mount/fs.go b/cmd/mount/fs.go index 71f1a0504..523268de3 100644 --- a/cmd/mount/fs.go +++ b/cmd/mount/fs.go @@ -68,6 +68,7 @@ func mountOptions(device string) (options []fuse.MountOption) { // returns an error, and an error channel for the serve process to // report an error when fusermount is called. func mount(f fs.Fs, mountpoint string) (<-chan error, error) { + fs.Debug(f, "Mounting on %q", mountpoint) c, err := fuse.Mount(mountpoint, mountOptions(f.Name()+":"+f.Root())...) if err != nil { return nil, err diff --git a/cmd/mount/read.go b/cmd/mount/read.go index f7232d77e..4739e5ac6 100644 --- a/cmd/mount/read.go +++ b/cmd/mount/read.go @@ -79,6 +79,14 @@ func (fh *ReadFileHandle) Read(ctx context.Context, req *fuse.ReadRequest, resp return errClosedFileHandle } if req.Offset != fh.offset { + // Are we attempting to seek beyond the end of the + // file - if so just return EOF leaving the underlying + // file in an unchanged state. + if req.Offset >= fh.o.Size() { + fs.Debug(fh.o, "ReadFileHandle.Read attempt to read beyond end of file: %d > %d", req.Offset, fh.o.Size()) + resp.Data = nil + return nil + } err := fh.seek(req.Offset) if err != nil { return err diff --git a/cmd/mount/read_test.go b/cmd/mount/read_test.go index 885d86435..f200aef89 100644 --- a/cmd/mount/read_test.go +++ b/cmd/mount/read_test.go @@ -90,6 +90,7 @@ func TestReadSeek(t *testing.T) { fd, err := os.Open(run.path("testfile")) assert.NoError(t, err) + // Seek to half way _, err = fd.Seek(5, 0) assert.NoError(t, err) @@ -97,6 +98,23 @@ func TestReadSeek(t *testing.T) { assert.NoError(t, err) assert.Equal(t, buf, []byte("HELLO")) + // Test seeking to the end + _, err = fd.Seek(10, 0) + assert.NoError(t, err) + + buf, err = ioutil.ReadAll(fd) + assert.NoError(t, err) + assert.Equal(t, buf, []byte("")) + + // Test seeking beyond the end + _, err = fd.Seek(1000000, 0) + assert.NoError(t, err) + + buf, err = ioutil.ReadAll(fd) + assert.NoError(t, err) + assert.Equal(t, buf, []byte("")) + + // Now back to the start _, err = fd.Seek(0, 0) assert.NoError(t, err)