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 {
|
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 := fs.walkDir(b, dirfd, d1.Name(), path.Join(relative, d1.Name()), d1, walkDirFn); err != nil {
|
||||||
if err == SkipDir {
|
if err == SkipDir {
|
||||||
break
|
break
|
||||||
|
|
|
@ -113,6 +113,10 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
||||||
return errors.New("filesystem: archive.Filesystem is unset")
|
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 {
|
if filesLen := len(a.Files); filesLen > 0 {
|
||||||
files := make([]string, filesLen)
|
files := make([]string, filesLen)
|
||||||
for i, f := range a.Files {
|
for i, f := range a.Files {
|
||||||
|
@ -167,11 +171,14 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
||||||
callback = a.callback()
|
callback = a.callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open the base directory we were provided.
|
||||||
dirfd, name, closeFd, err := fs.SafePath(a.BaseDirectory)
|
dirfd, name, closeFd, err := fs.SafePath(a.BaseDirectory)
|
||||||
defer closeFd()
|
defer closeFd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively walk the base directory.
|
||||||
return fs.WalkDirat(dirfd, name, func(dirfd int, name, relative string, d ufs.DirEntry, err error) error {
|
return fs.WalkDirat(dirfd, name, func(dirfd int, name, relative string, d ufs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// Callback function used to determine if a given file should be included in the archive
|
||||||
// being generated.
|
// being generated.
|
||||||
func (a *Archive) callback(opts ...walkFunc) walkFunc {
|
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 {
|
return func(dirfd int, name, relative string, d ufs.DirEntry) error {
|
||||||
// Skip directories because we are walking them recursively.
|
// Skip directories because we are walking them recursively.
|
||||||
if d.IsDir() {
|
if d.IsDir() {
|
||||||
return nil
|
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
|
// Call the additional options passed to this callback function. If any of them return
|
||||||
// a non-nil error we will exit immediately.
|
// a non-nil error we will exit immediately.
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user