Preserve directory traversal failure phases

This commit is contained in:
2026-10-25 21:33:36 +00:00
parent 877c497325
commit 8aba43da38
6 changed files with 287 additions and 24 deletions

View File

@@ -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
}