Skip to content

Commit 3394750

Browse files
committed
Fix panic closing file which is never read
Signed-off-by: Derek McGowan <derek@mcg.dev>
1 parent c314618 commit 3394750

3 files changed

Lines changed: 26 additions & 4 deletions

File tree

erofs.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,10 @@ func (b *file) Read(p []byte) (int, error) {
910910
}
911911

912912
func (b *file) Close() error {
913-
b.info.cached = nil
913+
if b.info != nil && b.info.cached != nil {
914+
b.img.putBlock(b.info.cached)
915+
b.info.cached = nil
916+
}
914917
return nil
915918
}
916919

erofs_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"io/fs"
78
"os"
89
"path/filepath"
910
"runtime"
@@ -140,10 +141,10 @@ func BenchmarkLookup(b *testing.B) {
140141
for range b.N {
141142
f, err := fsys.Open(bc.path)
142143
if err != nil {
143-
if bc.name == "bigdir-notfound" {
144-
continue
144+
if !errors.Is(err, fs.ErrNotExist) {
145+
b.Fatal(err)
145146
}
146-
b.Fatal(err)
147+
continue
147148
}
148149
_ = f.Close()
149150
}

internal/erofstest/testcase.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ var Basic TestCase = &testCase{
273273

274274
// ReadLink on a regular file should return ErrInvalid.
275275
CheckReadLinkFile(t, fsys, "in-root.txt")
276+
277+
// Close without reading should not panic.
278+
CheckOpenClose(t, fsys, "in-root.txt")
279+
CheckOpenClose(t, fsys, "usr/lib/testdir")
276280
},
277281
}
278282

@@ -766,3 +770,17 @@ func CheckReadLinkFile(t testing.TB, fsys fs.FS, name string) {
766770
t.Errorf("ReadLink(%s): got %v, want fs.ErrInvalid", name, err)
767771
}
768772
}
773+
774+
// CheckOpenClose verifies that opening and immediately closing a file
775+
// without reading does not panic.
776+
func CheckOpenClose(t testing.TB, fsys fs.FS, name string) {
777+
t.Helper()
778+
f, err := fsys.Open(name)
779+
if err != nil {
780+
t.Errorf("Open(%s): %v", name, err)
781+
return
782+
}
783+
if err := f.Close(); err != nil {
784+
t.Errorf("Close(%s): %v", name, err)
785+
}
786+
}

0 commit comments

Comments
 (0)