fix: Prevent deleting non-empty directories
This commit is contained in:
@@ -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")
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user