mirror of https://github.com/knative/func.git
Go tar (#2672)
* Fixed pod readiness check Detect also if pod did not exited prematurely. Signed-off-by: Matej Vašek <mvasek@redhat.com> * Removed dependency on sh/tar from alpine image This commit removes depencency on sh and tar binaries by implementing the logic in our func-util binary. Signed-off-by: Matej Vašek <mvasek@redhat.com> --------- Signed-off-by: Matej Vašek <mvasek@redhat.com>
This commit is contained in:
parent
23668cbf36
commit
4de372564a
|
@ -34,6 +34,7 @@ COPY --from=builder /workspace/func-util /usr/local/bin/
|
||||||
RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy && \
|
RUN ln -s /usr/local/bin/func-util /usr/local/bin/deploy && \
|
||||||
ln -s /usr/local/bin/func-util /usr/local/bin/scaffold && \
|
ln -s /usr/local/bin/func-util /usr/local/bin/scaffold && \
|
||||||
ln -s /usr/local/bin/func-util /usr/local/bin/s2i && \
|
ln -s /usr/local/bin/func-util /usr/local/bin/s2i && \
|
||||||
|
ln -s /usr/local/bin/func-util /usr/local/bin/sh && \
|
||||||
ln -s /usr/local/bin/func-util /usr/local/bin/socat
|
ln -s /usr/local/bin/func-util /usr/local/bin/socat
|
||||||
|
|
||||||
LABEL \
|
LABEL \
|
||||||
|
|
|
@ -10,8 +10,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/openshift/source-to-image/pkg/cmd/cli"
|
"github.com/openshift/source-to-image/pkg/cmd/cli"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
|
@ -20,6 +23,7 @@ import (
|
||||||
"knative.dev/func/pkg/k8s"
|
"knative.dev/func/pkg/k8s"
|
||||||
"knative.dev/func/pkg/knative"
|
"knative.dev/func/pkg/knative"
|
||||||
"knative.dev/func/pkg/scaffolding"
|
"knative.dev/func/pkg/scaffolding"
|
||||||
|
"knative.dev/func/pkg/tar"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -46,6 +50,8 @@ func main() {
|
||||||
cmd = s2iCmd
|
cmd = s2iCmd
|
||||||
case "socat":
|
case "socat":
|
||||||
cmd = socat
|
cmd = socat
|
||||||
|
case "sh":
|
||||||
|
cmd = sh
|
||||||
}
|
}
|
||||||
|
|
||||||
err := cmd(ctx)
|
err := cmd(ctx)
|
||||||
|
@ -167,3 +173,18 @@ func (d deployDecorator) UpdateLabels(function fn.Function, labels map[string]st
|
||||||
}
|
}
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sh(ctx context.Context) error {
|
||||||
|
if !slices.Equal(os.Args[1:], []string{"-c", "umask 0000 && exec tar -xmf -"}) {
|
||||||
|
return fmt.Errorf("this is a fake sh (only for backward compatiblility purposes)")
|
||||||
|
}
|
||||||
|
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot get working directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
unix.Umask(0)
|
||||||
|
|
||||||
|
return tar.Extract(os.Stdin, wd)
|
||||||
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -53,6 +53,7 @@ require (
|
||||||
golang.org/x/net v0.34.0
|
golang.org/x/net v0.34.0
|
||||||
golang.org/x/oauth2 v0.24.0
|
golang.org/x/oauth2 v0.24.0
|
||||||
golang.org/x/sync v0.10.0
|
golang.org/x/sync v0.10.0
|
||||||
|
golang.org/x/sys v0.29.0
|
||||||
golang.org/x/term v0.28.0
|
golang.org/x/term v0.28.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
@ -272,7 +273,6 @@ require (
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/mod v0.22.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/sys v0.29.0 // indirect
|
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
golang.org/x/time v0.7.0 // indirect
|
golang.org/x/time v0.7.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||||
|
|
|
@ -423,6 +423,11 @@ func podReady(ctx context.Context, core v1.CoreV1Interface, podName, namespace s
|
||||||
d <- nil
|
d <- nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if status.State.Terminated != nil {
|
||||||
|
msg, _ := GetPodLogs(ctx, namespace, podName, podName)
|
||||||
|
d <- fmt.Errorf("pod prematurely exited (output: %q, exitcode: %d)", msg, status.State.Terminated.ExitCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
if status.State.Waiting != nil {
|
if status.State.Waiting != nil {
|
||||||
switch status.State.Waiting.Reason {
|
switch status.State.Waiting.Reason {
|
||||||
case "ErrImagePull",
|
case "ErrImagePull",
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,104 @@
|
||||||
|
package tar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Extract(input io.Reader, destDir string) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
des, err := os.ReadDir(destDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot read dest dir: %w", err)
|
||||||
|
}
|
||||||
|
for _, de := range des {
|
||||||
|
err = os.RemoveAll(filepath.Join(destDir, de.Name()))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot purge dest dir: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r := tar.NewReader(input)
|
||||||
|
|
||||||
|
var first bool = true
|
||||||
|
for {
|
||||||
|
var hdr *tar.Header
|
||||||
|
hdr, err = r.Next()
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
if first {
|
||||||
|
// mimic tar output on empty input
|
||||||
|
return fmt.Errorf("does not look like a tar")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
first = false
|
||||||
|
|
||||||
|
name := hdr.Name
|
||||||
|
linkname := hdr.Linkname
|
||||||
|
if strings.Contains(name, "..") {
|
||||||
|
return fmt.Errorf("name contains '..': %s", name)
|
||||||
|
}
|
||||||
|
if path.IsAbs(linkname) {
|
||||||
|
return fmt.Errorf("absolute symlink: %s->%s", name, linkname)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(path.Clean(path.Join(path.Dir(name), linkname)), "..") {
|
||||||
|
return fmt.Errorf("link target escapes: %s->%s", name, linkname)
|
||||||
|
}
|
||||||
|
|
||||||
|
var destPath, rel string
|
||||||
|
destPath = filepath.Join(destDir, filepath.FromSlash(name))
|
||||||
|
rel, err = filepath.Rel(destDir, destPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot get relative path: %w", err)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(rel, "..") {
|
||||||
|
return fmt.Errorf("name escapes")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure parent
|
||||||
|
err = os.MkdirAll(filepath.Dir(destPath), os.FileMode(hdr.Mode)&fs.ModePerm|0111)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot ensure parent: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case hdr.Typeflag == tar.TypeReg:
|
||||||
|
err = writeRegularFile(destPath, os.FileMode(hdr.Mode&0777), r)
|
||||||
|
case hdr.Typeflag == tar.TypeDir:
|
||||||
|
err = os.MkdirAll(destPath, os.FileMode(hdr.Mode)&fs.ModePerm)
|
||||||
|
case hdr.Typeflag == tar.TypeSymlink:
|
||||||
|
err = os.Symlink(linkname, destPath)
|
||||||
|
default:
|
||||||
|
_, _ = fmt.Printf("unsupported type flag: %d\n", hdr.Typeflag)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot create entry: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeRegularFile(target string, perm os.FileMode, content io.Reader) error {
|
||||||
|
f, err := os.OpenFile(target, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func(f *os.File) {
|
||||||
|
_ = f.Close()
|
||||||
|
}(f)
|
||||||
|
_, err = io.Copy(f, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
package tar_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
tarutil "knative.dev/func/pkg/tar"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
aTxt1 = "a.txt first revision"
|
||||||
|
bTxt1 = "b.txt first revision"
|
||||||
|
aTxt2 = "a.txt second revision"
|
||||||
|
bTxt2 = "b.txt second revision"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExtract(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
d := t.TempDir()
|
||||||
|
err = tarutil.Extract(tarballV1(t), d)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bs, err := os.ReadFile(filepath.Join(d, "dir/a.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s := string(bs)
|
||||||
|
if s != aTxt1 {
|
||||||
|
t.Errorf("unexpected data: %s", s)
|
||||||
|
}
|
||||||
|
bs, err = os.ReadFile(filepath.Join(d, "dir/b.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s = string(bs)
|
||||||
|
if s != bTxt1 {
|
||||||
|
t.Errorf("unexpected data: %s", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tarutil.Extract(tarballV2(t), d)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bs, err = os.ReadFile(filepath.Join(d, "dir/a.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s = string(bs)
|
||||||
|
if s != aTxt2 {
|
||||||
|
t.Errorf("unexpected data: %s", s)
|
||||||
|
}
|
||||||
|
bs, err = os.ReadFile(filepath.Join(d, "dir/b.txt"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s = string(bs)
|
||||||
|
if s != bTxt2 {
|
||||||
|
t.Errorf("unexpected data: %s", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tarballV1(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/a.txt",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(aTxt1)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = w.Write([]byte(aTxt1))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/data1",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(bTxt1)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = w.Write([]byte(bTxt1))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/b.txt",
|
||||||
|
Linkname: "data1",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func tarballV2(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/a.txt",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(aTxt2)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = w.Write([]byte(aTxt2))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/b.txt",
|
||||||
|
Linkname: "data2",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "dir/data2",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(bTxt2)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = w.Write([]byte(bTxt2))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buff
|
||||||
|
}
|
|
@ -0,0 +1,316 @@
|
||||||
|
package tar_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
tarutil "knative.dev/func/pkg/tar"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExtractErrors(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
createReader func(*testing.T) io.Reader
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "non escaping link",
|
||||||
|
createReader: nonEscapingSymlink,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing parent of regular file",
|
||||||
|
createReader: missingParentRegular,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing parent of link",
|
||||||
|
createReader: missingParentLink,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "absolute symlink",
|
||||||
|
createReader: absoluteSymlink,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "direct escape",
|
||||||
|
createReader: directEscape,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "indirect link escape",
|
||||||
|
createReader: indirectLinkEscape,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "indirect link escape with overwrite",
|
||||||
|
createReader: indirectLinkEscapeWithOverwrites,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "double dot in name",
|
||||||
|
createReader: doubleDotInName,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
d := t.TempDir()
|
||||||
|
if err := tarutil.Extract(tt.createReader(t), d); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Extract() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nonEscapingSymlink(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent",
|
||||||
|
Linkname: "..",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return &buff
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func absoluteSymlink(t *testing.T) io.Reader {
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "a.lnk",
|
||||||
|
Linkname: "/etc/shadow",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func directEscape(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
var msg = "I am free!!!"
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "../escaped.txt",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(msg)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = w.Write([]byte(msg))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func indirectLinkEscape(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
t.Skip("we are not checking for this since the core utils tar does not too")
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent",
|
||||||
|
Linkname: "..",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "escape",
|
||||||
|
Linkname: "subdir/parent/..",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func indirectLinkEscapeWithOverwrites(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
t.Skip("we are not checking for this since the core utils tar does not too")
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "escape",
|
||||||
|
Linkname: "subdir/parent/..",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent",
|
||||||
|
Linkname: "..",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func doubleDotInName(t *testing.T) io.Reader {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent",
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "subdir/parent/../../a.txt",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: 0644,
|
||||||
|
Size: 0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func missingParentRegular(t *testing.T) io.Reader {
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "missing/a.txt",
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Size: 0,
|
||||||
|
Mode: 0644,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buff
|
||||||
|
}
|
||||||
|
|
||||||
|
func missingParentLink(t *testing.T) io.Reader {
|
||||||
|
var err error
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
w := tar.NewWriter(&buff)
|
||||||
|
defer func(w *tar.Writer) {
|
||||||
|
_ = w.Close()
|
||||||
|
}(w)
|
||||||
|
err = w.WriteHeader(&tar.Header{
|
||||||
|
Name: "missing/a.lnk",
|
||||||
|
Linkname: "a.txt",
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Mode: 0777,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buff
|
||||||
|
}
|
Loading…
Reference in New Issue