Preserve directory traversal failure phases
This commit is contained in:
@@ -246,22 +246,36 @@ func TestNativeFilesystemDetectsRepeatedAndCyclicImports(t *testing.T) {
|
||||
}
|
||||
|
||||
type observedFilesystem struct {
|
||||
files fstest.MapFS
|
||||
opened int
|
||||
closed int
|
||||
fallback bool
|
||||
failRead string
|
||||
failStat string
|
||||
failDir string
|
||||
files fstest.MapFS
|
||||
opened int
|
||||
closed int
|
||||
fallback bool
|
||||
failOpen string
|
||||
failRead string
|
||||
failStat string
|
||||
failDir string
|
||||
failReadDir string
|
||||
readDirErr error
|
||||
failNoProgress string
|
||||
failClose string
|
||||
closeErr error
|
||||
failFallbackDir string
|
||||
fallbackErr error
|
||||
fallbackBeforeClose bool
|
||||
handles []*observedFile
|
||||
}
|
||||
|
||||
func (f *observedFilesystem) Open(name string) (fs.File, error) {
|
||||
if name == f.failOpen {
|
||||
return nil, fs.ErrNotExist
|
||||
}
|
||||
inner, err := f.files.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.opened++
|
||||
file := &observedFile{File: inner, owner: f, name: name}
|
||||
f.handles = append(f.handles, file)
|
||||
if directory, ok := inner.(fs.ReadDirFile); ok && !f.fallback {
|
||||
return &observedDirectoryFile{observedFile: file, directory: directory}, nil
|
||||
}
|
||||
@@ -272,20 +286,36 @@ func (f *observedFilesystem) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
if name == f.failDir {
|
||||
return nil, errors.New("tracking failure canary")
|
||||
}
|
||||
return fs.ReadDir(f.files, name)
|
||||
entries, err := fs.ReadDir(f.files, name)
|
||||
if name == f.failFallbackDir {
|
||||
for _, handle := range f.handles {
|
||||
if handle.name == name && !handle.closed {
|
||||
f.fallbackBeforeClose = true
|
||||
}
|
||||
}
|
||||
return entries, f.fallbackErr
|
||||
}
|
||||
return entries, err
|
||||
}
|
||||
|
||||
func (f *observedFilesystem) assertClosed(t *testing.T) {
|
||||
t.Helper()
|
||||
if f.opened == 0 || f.opened != f.closed {
|
||||
t.Fatalf("filesystem opens=%d closes=%d", f.opened, f.closed)
|
||||
if f.opened != f.closed || len(f.handles) != f.opened {
|
||||
t.Fatalf("filesystem opens=%d closes=%d handles=%d", f.opened, f.closed, len(f.handles))
|
||||
}
|
||||
for _, handle := range f.handles {
|
||||
if !handle.closed || handle.closeCalls != 1 {
|
||||
t.Errorf("filesystem handle %q closed=%t close calls=%d", handle.name, handle.closed, handle.closeCalls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type observedFile struct {
|
||||
fs.File
|
||||
owner *observedFilesystem
|
||||
name string
|
||||
owner *observedFilesystem
|
||||
name string
|
||||
closed bool
|
||||
closeCalls int
|
||||
}
|
||||
|
||||
func (f *observedFile) Read(data []byte) (int, error) {
|
||||
@@ -304,7 +334,16 @@ func (f *observedFile) Stat() (fs.FileInfo, error) {
|
||||
|
||||
func (f *observedFile) Close() error {
|
||||
f.owner.closed++
|
||||
return f.File.Close()
|
||||
f.closeCalls++
|
||||
f.closed = true
|
||||
err := f.File.Close()
|
||||
if f.name == f.owner.failClose {
|
||||
if f.owner.closeErr != nil {
|
||||
return f.owner.closeErr
|
||||
}
|
||||
return fs.ErrNotExist
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type observedDirectoryFile struct {
|
||||
@@ -316,5 +355,15 @@ func (f *observedDirectoryFile) ReadDir(count int) ([]fs.DirEntry, error) {
|
||||
if f.name == f.owner.failDir {
|
||||
return nil, errors.New("tracking failure canary")
|
||||
}
|
||||
return f.directory.ReadDir(count)
|
||||
if f.name == f.owner.failNoProgress {
|
||||
return nil, nil
|
||||
}
|
||||
entries, err := f.directory.ReadDir(count)
|
||||
if f.name == f.owner.failReadDir {
|
||||
if f.owner.readDirErr != nil {
|
||||
return entries, f.owner.readDirErr
|
||||
}
|
||||
return entries, fs.ErrNotExist
|
||||
}
|
||||
return entries, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user