fix: Prevent deleting non-empty directories

This commit is contained in:
Felicitas Pojtinger
2022-01-12 20:41:24 +01:00
parent b0c7e8cd55
commit a83f28809f
3 changed files with 110 additions and 20 deletions

View File

@@ -43,5 +43,6 @@ var (
ErrWriteCacheTypeUnsupported = errors.New("write cache type unsupported")
ErrWriteCacheTypeUnknown = errors.New("write cache type unknown")
ErrNoRootDirectory = errors.New("root directory could not be found")
ErrNoRootDirectory = errors.New("root directory could not be found")
ErrDirectoryNotEmpty = errors.New("directory not empty")
)

View File

@@ -446,6 +446,40 @@ func (f *STFS) Remove(name string) error {
f.ioLock.Lock()
defer f.ioLock.Unlock()
hdr, err := inventory.Stat(
f.metadata,
name,
false,
f.onHeader,
)
if err != nil {
if err == sql.ErrNoRows {
return os.ErrNotExist
}
return err
}
if hdr.Typeflag == tar.TypeDir {
hdrs, err := inventory.List(
f.metadata,
name,
-1,
f.onHeader,
)
if err != nil {
return err
}
if len(hdrs) > 0 {
return config.ErrDirectoryNotEmpty
}
}
return f.writeOps.Delete(name)
}

View File

@@ -1372,27 +1372,82 @@ var removeTests = []struct {
},
false,
},
// FIXME: STFS can delete directories using `Remove` even if it isn't empty
// {
// "Can not remove /mydir if it is a directory and not empty",
// removeArgs{"/mydir"},
// true,
// func(f afero.Fs) error {
// if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
// return err
// }
{
"Can not remove /mydir if it is a directory and not empty",
removeArgs{"/mydir"},
true,
func(f afero.Fs) error {
if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
// if _, err := f.Create("/mydir/test.txt"); err != nil {
// return err
// }
if _, err := f.Create("/mydir/test.txt"); err != nil {
return err
}
// return nil
// },
// func(f afero.Fs) error {
// return nil
// },
// false,
// },
return nil
},
func(f afero.Fs) error {
return nil
},
false,
},
{
"Can not remove /mydir/subdir if it is a directory and not empty",
removeArgs{"/mydir/subdir"},
true,
func(f afero.Fs) error {
if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
if err := f.Mkdir("/mydir/subdir", os.ModePerm); err != nil {
return err
}
if _, err := f.Create("/mydir/subdir/test.txt"); err != nil {
return err
}
return nil
},
func(f afero.Fs) error {
if _, err := f.Stat("/mydir/subdir/test.txt"); !errors.Is(err, os.ErrNotExist) {
return err
}
if _, err := f.Stat("/mydir/subdir"); !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
},
false,
},
{
"Can remove /mydir/subdir if it is a directory and empty",
removeArgs{"/mydir/subdir"},
false,
func(f afero.Fs) error {
if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
if err := f.Mkdir("/mydir/subdir", os.ModePerm); err != nil {
return err
}
return nil
},
func(f afero.Fs) error {
if _, err := f.Stat("/mydir/subdir"); !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
},
false,
},
}
func TestSTFS_Remove(t *testing.T) {