From b50ff04cf3af4bee87bb38e95c3413d8bbf51690 Mon Sep 17 00:00:00 2001 From: greatroar <61184462+greatroar@users.noreply.github.com> Date: Thu, 27 Apr 2023 11:45:41 +0200 Subject: [PATCH] dump: Report filename with tar.ErrFieldTooLong Updates #4307. --- internal/dump/tar.go | 4 ++-- internal/dump/tar_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/internal/dump/tar.go b/internal/dump/tar.go index 6e87aabe5..df9ea429d 100644 --- a/internal/dump/tar.go +++ b/internal/dump/tar.go @@ -3,6 +3,7 @@ package dump import ( "archive/tar" "context" + "fmt" "os" "path/filepath" "strings" @@ -94,9 +95,8 @@ func (d *Dumper) dumpNodeTar(ctx context.Context, node *restic.Node, w *tar.Writ err = w.WriteHeader(header) if err != nil { - return errors.Wrap(err, "TarHeader") + return fmt.Errorf("writing header for %q: %w", node.Path, err) } - return d.writeNode(ctx, w, node) } diff --git a/internal/dump/tar_test.go b/internal/dump/tar_test.go index 0f2cb27a8..3556e6aeb 100644 --- a/internal/dump/tar_test.go +++ b/internal/dump/tar_test.go @@ -3,6 +3,8 @@ package dump import ( "archive/tar" "bytes" + "context" + "errors" "fmt" "io" "os" @@ -12,6 +14,8 @@ import ( "time" "github.com/restic/restic/internal/fs" + "github.com/restic/restic/internal/restic" + rtest "github.com/restic/restic/internal/test" ) func TestWriteTar(t *testing.T) { @@ -112,3 +116,29 @@ func checkTar(t *testing.T, testDir string, srcTar *bytes.Buffer) error { return nil } + +// #4307. +func TestFieldTooLong(t *testing.T) { + const maxSpecialFileSize = 1 << 20 // Unexported limit in archive/tar. + + node := restic.Node{ + Name: "file_with_xattr", + Path: "/file_with_xattr", + Type: "file", + Mode: 0644, + ExtendedAttributes: []restic.ExtendedAttribute{ + { + Name: "user.way_too_large", + Value: make([]byte, 2*maxSpecialFileSize), + }, + }, + } + + d := Dumper{format: "tar"} + err := d.dumpNodeTar(context.Background(), &node, tar.NewWriter(io.Discard)) + + // We want a tar.ErrFieldTooLong that has the filename. + rtest.Assert(t, errors.Is(err, tar.ErrFieldTooLong), "wrong type %T", err) + rtest.Assert(t, strings.Contains(err.Error(), node.Path), + "no filename in %q", err) +}