diff options
author | zeripath <art27@cantab.net> | 2021-05-12 21:42:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-12 22:42:07 +0200 |
commit | 720c192831a890d0a36b4c6720b60411fa4a0159 (patch) | |
tree | 9f3020c074fe9b113e22d6f2c601e8a36bf0ac49 /storage/filesystem/dotgit/reader.go | |
parent | e6e23391e4d044cc85e09b4420a2533715e7312d (diff) | |
download | go-git-720c192831a890d0a36b4c6720b60411fa4a0159.tar.gz |
plumbing: format/packfile, prevent large objects from being read into memory completely (#303)v5.4.0
This PR adds code to prevent large objects from being read into memory from packfiles or the filesystem.
Objects greater than 1Mb are now no longer directly stored in the cache
or read completely into memory.
Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'storage/filesystem/dotgit/reader.go')
-rw-r--r-- | storage/filesystem/dotgit/reader.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/storage/filesystem/dotgit/reader.go b/storage/filesystem/dotgit/reader.go new file mode 100644 index 0000000..a82ac94 --- /dev/null +++ b/storage/filesystem/dotgit/reader.go @@ -0,0 +1,79 @@ +package dotgit + +import ( + "fmt" + "io" + "os" + + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/format/objfile" + "github.com/go-git/go-git/v5/utils/ioutil" +) + +var _ (plumbing.EncodedObject) = &EncodedObject{} + +type EncodedObject struct { + dir *DotGit + h plumbing.Hash + t plumbing.ObjectType + sz int64 +} + +func (e *EncodedObject) Hash() plumbing.Hash { + return e.h +} + +func (e *EncodedObject) Reader() (io.ReadCloser, error) { + f, err := e.dir.Object(e.h) + if err != nil { + if os.IsNotExist(err) { + return nil, plumbing.ErrObjectNotFound + } + + return nil, err + } + r, err := objfile.NewReader(f) + if err != nil { + return nil, err + } + + t, size, err := r.Header() + if err != nil { + _ = r.Close() + return nil, err + } + if t != e.t { + _ = r.Close() + return nil, objfile.ErrHeader + } + if size != e.sz { + _ = r.Close() + return nil, objfile.ErrHeader + } + return ioutil.NewReadCloserWithCloser(r, f.Close), nil +} + +func (e *EncodedObject) SetType(plumbing.ObjectType) {} + +func (e *EncodedObject) Type() plumbing.ObjectType { + return e.t +} + +func (e *EncodedObject) Size() int64 { + return e.sz +} + +func (e *EncodedObject) SetSize(int64) {} + +func (e *EncodedObject) Writer() (io.WriteCloser, error) { + return nil, fmt.Errorf("Not supported") +} + +func NewEncodedObject(dir *DotGit, h plumbing.Hash, t plumbing.ObjectType, size int64) *EncodedObject { + return &EncodedObject{ + dir: dir, + h: h, + t: t, + sz: size, + } +} |