From 0dcec81699395dc0728137c5858849cf9190fb2f Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Wed, 22 Mar 2023 17:03:23 +0100 Subject: [PATCH] fix: tar without compression --- go.mod | 2 -- go.sum | 2 -- pkg/providers/gogit/git.go | 7 ++---- pkg/providers/gogit/tar.go | 50 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 pkg/providers/gogit/tar.go diff --git a/go.mod b/go.mod index 3ed5179..8df21ae 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/Masterminds/semver/v3 v3.2.0 github.com/fluxcd/pkg/apis/meta v0.19.0 github.com/fluxcd/pkg/runtime v0.27.0 - github.com/fluxcd/pkg/tar v0.2.0 github.com/go-git/go-git/v5 v5.6.0 github.com/go-logr/logr v1.2.3 github.com/open-component-model/ocm-controller v0.4.0 @@ -51,7 +50,6 @@ require ( github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a // indirect github.com/containers/ocicrypt v1.1.5 // indirect github.com/containers/storage v1.42.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa // indirect github.com/docker/cli v23.0.1+incompatible // indirect diff --git a/go.sum b/go.sum index a8333d9..13d7a73 100644 --- a/go.sum +++ b/go.sum @@ -475,8 +475,6 @@ github.com/fluxcd/pkg/apis/meta v0.19.0 h1:CX75e/eaRWZDTzNdMSWomY1InlssLKcS8GQDS github.com/fluxcd/pkg/apis/meta v0.19.0/go.mod h1:7b6prDPsViyAzoY7eRfSPS0/MbXpGGsOMvRq2QrTKa4= github.com/fluxcd/pkg/runtime v0.27.0 h1:zVA95Z0KvNjvZxEZhvIbJyJIwtaiv1aVttHZ4YB/FzY= github.com/fluxcd/pkg/runtime v0.27.0/go.mod h1:fC1l4Wv1hnsqPKB46eDZBXF8RMZm5FXeU4bnJkwGkqk= -github.com/fluxcd/pkg/tar v0.2.0 h1:HEUHgONQYsJGeZZ4x6h5nQU9Aox1I4T3bOp1faWTqf8= -github.com/fluxcd/pkg/tar v0.2.0/go.mod h1:w0/TOC7kwBJhnSJn7TCABkc/I7ib1f2Yz6vOsbLBnhw= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= diff --git a/pkg/providers/gogit/git.go b/pkg/providers/gogit/git.go index 1fdf84a..b8a2dc5 100644 --- a/pkg/providers/gogit/git.go +++ b/pkg/providers/gogit/git.go @@ -5,15 +5,12 @@ package gogit import ( - "compress/gzip" "context" - "errors" "fmt" "os" "path/filepath" "time" - "github.com/fluxcd/pkg/tar" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" @@ -99,8 +96,8 @@ func (g *Git) Push(ctx context.Context, opts *pkg.PushOptions) (string, error) { // we only care about the error if it is NOT a header error. Otherwise, we assume the content // wasn't compressed. - if err = tar.Untar(blob, dir, tar.WithMaxUntarSize(-1)); err != nil && !errors.Is(err, gzip.ErrHeader) { - return "", fmt.Errorf("failed to untar first layer: %w", err) + if err = Untar(blob, dir); err != nil { + return "", fmt.Errorf("failed to untar content: %w", err) } // Add all extracted files. diff --git a/pkg/providers/gogit/tar.go b/pkg/providers/gogit/tar.go new file mode 100644 index 0000000..ef08df5 --- /dev/null +++ b/pkg/providers/gogit/tar.go @@ -0,0 +1,50 @@ +package gogit + +import ( + "archive/tar" + "errors" + "fmt" + "io" + "os" + "path/filepath" +) + +// Untar writes a tar stream to a filesystem. +func Untar(in io.Reader, dir string) error { + tr := tar.NewReader(in) + for { + header, err := tr.Next() + if err != nil { + if errors.Is(err, io.EOF) { + return nil + } + return err + } + + abs := filepath.Join(dir, header.Name) + + switch header.Typeflag { + case tar.TypeDir: + if err := os.MkdirAll(abs, os.FileMode(header.Mode)); err != nil { + return fmt.Errorf("unable to create directory %s: %w", header.Name, err) + } + case tar.TypeReg: + file, err := os.OpenFile(abs, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(header.Mode)) + if err != nil { + return fmt.Errorf("unable to open file %s: %w", header.Name, err) + } + //nolint:gosec // We don't know what size limit we could set, the tar + // archive can be an image layer and that can even reach the gigabyte range. + // For now, we acknowledge the risk. + // + // We checked other softwares and tried to figure out how they manage this, + // but it's handled the same way. + if _, err := io.Copy(file, tr); err != nil { + return fmt.Errorf("unable to copy tar file to filesystem: %w", err) + } + if err := file.Close(); err != nil { + return fmt.Errorf("unable to close file %s: %w", header.Name, err) + } + } + } +}