fix: don't follow symlinks in disk usage

pull/3756/head
Laurynas Gadliauskas 2021-06-17 13:40:42 +03:00
parent d9aaa551a2
commit d5ca315102
4 changed files with 24 additions and 46 deletions

View File

@ -62,8 +62,13 @@ func CopyDir(fs afero.Fs, source, dest string) error {
return nil
}
func DiskUsage(fs afero.Fs, path string, maxDepth int) (size, inodes int64, err error) {
info, err := fs.Stat(path)
func DiskUsage(fs afero.Fs, path string) (size, inodes int64, err error) {
lst, ok := fs.(afero.Lstater)
if !ok {
return 0, 0, err
}
info, _, err := lst.LstatIfPossible(path)
if err != nil {
return 0, 0, err
}
@ -71,36 +76,24 @@ func DiskUsage(fs afero.Fs, path string, maxDepth int) (size, inodes int64, err
size = info.Size()
inodes = int64(1)
// don't follow symlinks
if !info.IsDir() {
return size, inodes, err
}
if maxDepth < 1 {
return size, inodes, err
}
dir, err := fs.Open(path)
if err != nil {
return size, inodes, err
}
defer dir.Close()
fis, err := dir.Readdir(-1)
afs := &afero.Afero{Fs: fs}
dir, err := afs.ReadDir(path)
if err != nil {
return size, inodes, err
}
for _, fi := range fis {
if fi.Name() == "." || fi.Name() == ".." {
continue
}
s, i, e := DiskUsage(fs, filepath.Join(path, fi.Name()), maxDepth-1)
if e != nil {
return size, inodes, e
}
for _, fi := range dir {
s, i, e := DiskUsage(fs, filepath.Join(path, fi.Name()))
if e == nil {
size += s
inodes += i
}
}
return size, inodes, err
}

View File

@ -52,7 +52,7 @@ func TestDiskUsageOnFile(t *testing.T) {
}
fs := afero.NewBasePathFs(afero.NewOsFs(), cwd)
size, inodes, err := DiskUsage(fs, filepath.Join(RootTestDir, "test_file"), 100)
size, inodes, err := DiskUsage(fs, filepath.Join(RootTestDir, "test_file"))
require.NoError(t, err)
require.Equal(t, int64(9), size)
@ -72,7 +72,7 @@ func TestDiskUsageOnNestedDir(t *testing.T) {
}
fs := afero.NewBasePathFs(afero.NewOsFs(), cwd)
size, inodes, err := DiskUsage(fs, filepath.Join(RootTestDir, "child_dir"), 100)
size, inodes, err := DiskUsage(fs, filepath.Join(RootTestDir, "child_dir"))
require.NoError(t, err)
require.Equal(t, int64(105), size)
@ -92,29 +92,9 @@ func TestDiskUsageOnRootDir(t *testing.T) {
}
fs := afero.NewBasePathFs(afero.NewOsFs(), cwd)
size, inodes, err := DiskUsage(fs, RootTestDir, 100)
size, inodes, err := DiskUsage(fs, RootTestDir)
require.NoError(t, err)
require.Equal(t, int64(242), size)
require.Equal(t, int64(4), inodes)
}
func TestDiskUsageOnRootDirStopsAtDepthLimit(t *testing.T) {
err := createFileStructure()
if err != nil {
t.Errorf("createFileStructure() failed: %s", err)
}
defer cleanupFileStructure()
cwd, err := os.Getwd()
if err != nil {
t.Errorf("Getwd() failed: %s", err)
}
fs := afero.NewBasePathFs(afero.NewOsFs(), cwd)
size, inodes, err := DiskUsage(fs, RootTestDir, 1)
require.NoError(t, err)
require.Equal(t, int64(233), size)
require.Equal(t, int64(3), inodes)
}

View File

@ -1,4 +1,5 @@
import { users as api } from "@/api";
import { quotaExists } from "@/utils/constants";
const state = {
inodes: null,
@ -14,6 +15,10 @@ const mutations = {
const actions = {
fetch: async (context, delay = 0) => {
if (!quotaExists) {
return;
}
setTimeout(async () => {
try {
let data = await api.getQuota();

View File

@ -43,7 +43,7 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
}
if r.URL.Query().Get("disk_usage") == "true" {
du, inodes, err := fileutils.DiskUsage(file.Fs, file.Path, 100)
du, inodes, err := fileutils.DiskUsage(file.Fs, file.Path)
if err != nil {
return http.StatusInternalServerError, err
}