Skip to content

Commit

Permalink
Fix missing bounds checking in UnionFile.Readdir
Browse files Browse the repository at this point in the history
It will now return io.EOF at the end of the directory view.

Fixes #194
  • Loading branch information
bep committed Jan 30, 2019
1 parent a5d6946 commit f4711e4
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
70 changes: 70 additions & 0 deletions composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package afero
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"testing"
Expand Down Expand Up @@ -401,3 +402,72 @@ func TestCacheOnReadFsNotInLayer(t *testing.T) {
}
fh.Close()
}

// #194
func TestUniontFileReaddirEmpty(t *testing.T) {
osFs := NewOsFs()

base := NewMemMapFs()
overlay := NewMemMapFs()
ufs := &CopyOnWriteFs{base: base, layer: overlay}
mem := NewMemMapFs()

// The OS file will return io.EOF on end of directory.
for _, fs := range []Fs{osFs, ufs, mem} {
baseDir, err := TempDir(fs, "", "empty-dir")
if err != nil {
t.Fatal(err)
}

f, err := fs.Open(baseDir)
if err != nil {
t.Fatal(err)
}

names, err := f.Readdirnames(1)
if err != io.EOF {
t.Fatal(err)
}

if len(names) != 0 {
t.Fatal("should be empty")
}

f.Close()

fs.RemoveAll(baseDir)
}
}

func TestUniontFileReaddirAskForTooMany(t *testing.T) {
base := &MemMapFs{}
overlay := &MemMapFs{}

for i := 0; i < 5; i++ {
WriteFile(base, fmt.Sprintf("file%d.txt", i), []byte("afero"), 0777)
}

ufs := &CopyOnWriteFs{base: base, layer: overlay}

f, err := ufs.Open("")
if err != nil {
t.Fatal(err)
}

defer f.Close()

names, err := f.Readdirnames(6)
if err != nil {
t.Fatal(err)
}

if len(names) != 5 {
t.Fatal(names)
}

// End of directory
_, err = f.Readdirnames(3)
if err != io.EOF {
t.Fatal(err)
}
}
11 changes: 11 additions & 0 deletions unionFile.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ var defaultUnionMergeDirsFn = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, err

// Readdir will weave the two directories together and
// return a single view of the overlayed directories
// At the end of the directory view, the error is io.EOF.
func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error) {
var merge DirsMerger = f.Merger
if merge == nil {
Expand Down Expand Up @@ -185,9 +186,19 @@ func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error) {
}
f.files = append(f.files, merged...)
}

if f.off >= len(f.files) {
return nil, io.EOF
}

if c == -1 {
return f.files[f.off:], nil
}

if c > len(f.files) {
c = len(f.files)
}

defer func() { f.off += c }()
return f.files[f.off:c], nil
}
Expand Down

0 comments on commit f4711e4

Please sign in to comment.