1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
package lfs
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"io"
"os"
"github.com/git-lfs/git-lfs/v3/errors"
"github.com/git-lfs/git-lfs/v3/tools"
)
type cleanedAsset struct {
Filename string
*Pointer
}
func (f *GitFilter) Clean(reader io.Reader, fileName string, fileSize int64, cb tools.CopyCallback) (*cleanedAsset, error) {
extensions, err := f.cfg.SortedExtensions()
if err != nil {
return nil, err
}
var oid string
var size int64
var tmp *os.File
var exts []*PointerExtension
if len(extensions) > 0 {
request := &pipeRequest{"clean", reader, fileName, extensions}
var response pipeResponse
if response, err = pipeExtensions(f.cfg, request); err != nil {
return nil, err
}
oid = response.results[len(response.results)-1].oidOut
tmp = response.file
var stat os.FileInfo
if stat, err = os.Stat(tmp.Name()); err != nil {
return nil, err
}
size = stat.Size()
for _, result := range response.results {
if result.oidIn != result.oidOut {
ext := NewPointerExtension(result.name, len(exts), result.oidIn)
exts = append(exts, ext)
}
}
} else {
oid, size, tmp, err = f.copyToTemp(reader, fileSize, cb)
if err != nil {
return nil, err
}
}
pointer := NewPointer(oid, size, exts)
return &cleanedAsset{tmp.Name(), pointer}, err
}
func (f *GitFilter) copyToTemp(reader io.Reader, fileSize int64, cb tools.CopyCallback) (oid string, size int64, tmp *os.File, err error) {
tmp, err = TempFile(f.cfg, "")
if err != nil {
return
}
defer tmp.Close()
oidHash := sha256.New()
writer := io.MultiWriter(oidHash, tmp)
if fileSize <= 0 {
cb = nil
}
ptr, buf, err := DecodeFrom(reader)
by := make([]byte, blobSizeCutoff)
n, rerr := buf.Read(by)
by = by[:n]
if rerr != nil || (err == nil && len(by) < blobSizeCutoff) {
err = errors.NewCleanPointerError(ptr, by)
return
}
var from io.Reader = bytes.NewReader(by)
if fileSize < 0 || int64(len(by)) < fileSize {
// If there is still more data to be read from the file, tack on
// the original reader and continue the read from there.
from = io.MultiReader(from, reader)
}
size, err = tools.CopyWithCallback(writer, from, fileSize, cb)
if err != nil {
return
}
oid = hex.EncodeToString(oidHash.Sum(nil))
return
}
func (a *cleanedAsset) Teardown() error {
return os.Remove(a.Filename)
}
|