From 67e137a474ef7fd18b03599c41d5545c121eca61 Mon Sep 17 00:00:00 2001 From: Caj Larsson Date: Tue, 3 May 2022 18:45:06 +0800 Subject: [PATCH] fix: #8 content size lies --- dataswamp/namespace/valueobjects.go | 6 +++++- dataswamp/services.go | 17 ++++++++++++++++- dataswamp/services_test.go | 28 ++++++++++++++++++++++++++++ dataswamp/swampfile/entities.go | 16 +++++++++------- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/dataswamp/namespace/valueobjects.go b/dataswamp/namespace/valueobjects.go index eb7f0c5..5b0e4a6 100644 --- a/dataswamp/namespace/valueobjects.go +++ b/dataswamp/namespace/valueobjects.go @@ -6,7 +6,11 @@ type FileSizeQuota struct { } func (f *FileSizeQuota) Allows(size int64) bool { - return f.CurrentUsage+size <= f.AllowanceKB + return f.Remaining() >= size +} + +func (f *FileSizeQuota) Remaining() int64 { + return f.AllowanceKB - f.CurrentUsage } func (f *FileSizeQuota) Add(size int64) error { diff --git a/dataswamp/services.go b/dataswamp/services.go index 6dcca34..f921f84 100644 --- a/dataswamp/services.go +++ b/dataswamp/services.go @@ -73,7 +73,22 @@ func (s SwampFileService) SaveFile(ref swampfile.FileReference, src io.Reader, s return err } - io.Copy(f, src) + written, err := io.CopyN(f, src, size) + + if written < size { + s.swamp_file_repo.Delete(ref.Path, strconv.FormatInt(ns.ID, 10)) + return swampfile.ErrContentSizeExaggerated + } + + var buf = make([]byte, 1) + + overread, err :=src.Read(buf) + + if overread > 0 || err != io.EOF { + s.swamp_file_repo.Delete(ref.Path, strconv.FormatInt(ns.ID, 10)) + return swampfile.ErrContentSizeExceeded + } + f.Close() ns.FileQuota.Add(size) s.namespace_repo.Update(ns.ID, *ns) diff --git a/dataswamp/services_test.go b/dataswamp/services_test.go index b63deea..c6a8d34 100644 --- a/dataswamp/services_test.go +++ b/dataswamp/services_test.go @@ -105,3 +105,31 @@ func TestPathStrictMode(t *testing.T) { err = s.SaveFile(ref, ns_file, int64(ns_file.Len())) is.Equal(err, swampfile.ErrUnacceptablePath) } + + +func TestQuotaWithContenSizeLieOver(t *testing.T) { + is := is.New(t) + s := NewTestSwampFileService() + + largefakefile := bytes.NewBufferString("") + + for largefakefile.Len() < 64000 { + _, _ = largefakefile.WriteString("A very repetitive file") + } + + err := s.SaveFile(file_ref3, largefakefile, int64(10)) + + is.Equal(err, swampfile.ErrContentSizeExceeded) +} + + +func TestQuotaWithContenSizeLieUnder(t *testing.T) { + is := is.New(t) + s := NewTestSwampFileService() + + largefakefile := bytes.NewBufferString("small") + + err := s.SaveFile(file_ref3, largefakefile, int64(1024)) + + is.Equal(err, swampfile.ErrContentSizeExaggerated) +} diff --git a/dataswamp/swampfile/entities.go b/dataswamp/swampfile/entities.go index 5f51a61..bbab94c 100644 --- a/dataswamp/swampfile/entities.go +++ b/dataswamp/swampfile/entities.go @@ -13,11 +13,13 @@ type SwampFile struct { } var ( - ErrDuplicate = errors.New("record already exists") - ErrExceedQuota = errors.New("file too large") - ErrQuotaInvalid = errors.New("quota invalid") - ErrNotExists = errors.New("row not exists") - ErrUpdateFailed = errors.New("update failed") - ErrDeleteFailed = errors.New("delete failed") - ErrUnacceptablePath = errors.New("unacceptable path") + ErrDuplicate = errors.New("record already exists") + ErrExceedQuota = errors.New("file too large") + ErrQuotaInvalid = errors.New("quota invalid") + ErrContentSizeExceeded = errors.New("content size exceeded") + ErrContentSizeExaggerated = errors.New("content size exaggerated") + ErrNotExists = errors.New("row not exists") + ErrUpdateFailed = errors.New("update failed") + ErrDeleteFailed = errors.New("delete failed") + ErrUnacceptablePath = errors.New("unacceptable path") )