server(filesystem): fix archives in subdirectories
When creating an archive starting from a subdirectory instead of the root of a server's filesystem, the walker would treat the paths as if they where relative to the parent of the subdirectory, instead of as descendants of the subdirectory. Fixes https://github.com/pterodactyl/panel/issues/5030
This commit is contained in:
parent
979df34392
commit
ac9bd1d95e
|
@ -66,6 +66,13 @@ func (fs *UnixFS) walkDir(b []byte, parentfd int, name, relative string, d DirEn
|
|||
}
|
||||
|
||||
for _, d1 := range dirs {
|
||||
// TODO: the path.Join on this line may actually be partially incorrect.
|
||||
// If we are not walking starting at the root, relative will contain the
|
||||
// name of the directory we are starting the walk from, which will be
|
||||
// relative to the root of the filesystem instead of from where the walk
|
||||
// was initiated from.
|
||||
//
|
||||
// ref; https://github.com/pterodactyl/panel/issues/5030
|
||||
if err := fs.walkDir(b, dirfd, d1.Name(), path.Join(relative, d1.Name()), d1, walkDirFn); err != nil {
|
||||
if err == SkipDir {
|
||||
break
|
||||
|
|
|
@ -113,6 +113,10 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||
return errors.New("filesystem: archive.Filesystem is unset")
|
||||
}
|
||||
|
||||
// The base directory may come with a prefixed `/`, strip it to prevent
|
||||
// problems.
|
||||
a.BaseDirectory = strings.TrimPrefix(a.BaseDirectory, "/")
|
||||
|
||||
if filesLen := len(a.Files); filesLen > 0 {
|
||||
files := make([]string, filesLen)
|
||||
for i, f := range a.Files {
|
||||
|
@ -167,11 +171,14 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||
callback = a.callback()
|
||||
}
|
||||
|
||||
// Open the base directory we were provided.
|
||||
dirfd, name, closeFd, err := fs.SafePath(a.BaseDirectory)
|
||||
defer closeFd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Recursively walk the base directory.
|
||||
return fs.WalkDirat(dirfd, name, func(dirfd int, name, relative string, d ufs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -188,12 +195,28 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||
// Callback function used to determine if a given file should be included in the archive
|
||||
// being generated.
|
||||
func (a *Archive) callback(opts ...walkFunc) walkFunc {
|
||||
// Get the base directory we need to strip when walking.
|
||||
//
|
||||
// This is important as when we are walking, the last part of the base directory
|
||||
// is present on all the paths we walk.
|
||||
var base string
|
||||
if a.BaseDirectory != "" {
|
||||
base = filepath.Base(a.BaseDirectory) + "/"
|
||||
}
|
||||
return func(dirfd int, name, relative string, d ufs.DirEntry) error {
|
||||
// Skip directories because we are walking them recursively.
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If base isn't empty, strip it from the relative path. This fixes an
|
||||
// issue when creating an archive starting from a nested directory.
|
||||
//
|
||||
// See https://github.com/pterodactyl/panel/issues/5030 for more details.
|
||||
if base != "" {
|
||||
relative = strings.TrimPrefix(relative, base)
|
||||
}
|
||||
|
||||
// Call the additional options passed to this callback function. If any of them return
|
||||
// a non-nil error we will exit immediately.
|
||||
for _, opt := range opts {
|
||||
|
|
Loading…
Reference in New Issue
Block a user