dump: Report filename with tar.ErrFieldTooLong

Updates #4307.
This commit is contained in:
greatroar 2023-04-27 11:45:41 +02:00
parent 49e32f3f8a
commit b50ff04cf3
2 changed files with 32 additions and 2 deletions

View file

@ -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)
}

View file

@ -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)
}