Skip to content

Commit

Permalink
fs: Fix stat of implied directory in ArchiveFS
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Dec 3, 2024
1 parent f35e651 commit 998c962
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func (f ArchiveFS) Stat(name string) (fs.FileInfo, error) {
if f.Path != "" {
fileInfo, err := os.Stat(f.Path)
if err != nil {
return nil, err
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat(a) %s: %w", name, err)}
}
return dirFileInfo{fileInfo}, nil
} else if f.Stream != nil {
Expand All @@ -521,28 +521,35 @@ func (f ArchiveFS) Stat(name string) (fs.FileInfo, error) {
if info, ok := f.contents[name]; ok {
return info, nil
}
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat %s: %w", name, fs.ErrNotExist)}
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat(b) %s: %w", name, fs.ErrNotExist)}
}

var archiveFile *os.File
var err error
if f.Stream == nil {
archiveFile, err = os.Open(f.Path)
if err != nil {
return nil, err
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat(c) %s: %w", name, err)}
}
defer archiveFile.Close()
}

var result FileInfo
var fallback fs.FileInfo // possibly needed if only an implied directory
handler := func(ctx context.Context, file FileInfo) error {
if err := ctx.Err(); err != nil {
return err
}
if path.Clean(file.NameInArchive) == name {
cleanName := path.Clean(file.NameInArchive)
if cleanName == name {
result = file
return fs.SkipAll
}
// it's possible the requested name is an implicit directory;
// remember if we see it along the way, just in case
if fallback == nil && strings.HasPrefix(cleanName, name) {
fallback = implicitDirInfo{implicitDirEntry{name}}
}
return nil
}
var inputStream io.Reader = archiveFile
Expand All @@ -551,10 +558,15 @@ func (f ArchiveFS) Stat(name string) (fs.FileInfo, error) {
}
err = f.Format.Extract(f.context(), inputStream, handler)
if err != nil && result.FileInfo == nil {
return nil, err
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat(d) %s: %w", name, fs.ErrNotExist)}
}
if result.FileInfo == nil {
return nil, fs.ErrNotExist
// looks like the requested name does not exist in the archive,
// but we can return some basic info if it was an implicit directory
if fallback != nil {
return fallback, nil
}
return nil, &fs.PathError{Op: "stat", Path: name, Err: fmt.Errorf("stat(e) %s: %w", name, fs.ErrNotExist)}
}
return result.FileInfo, nil
}
Expand Down

0 comments on commit 998c962

Please sign in to comment.