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 ( import (
"archive/tar" "archive/tar"
"context" "context"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -94,9 +95,8 @@ func (d *Dumper) dumpNodeTar(ctx context.Context, node *restic.Node, w *tar.Writ
err = w.WriteHeader(header) err = w.WriteHeader(header)
if err != nil { 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) return d.writeNode(ctx, w, node)
} }

View File

@ -3,6 +3,8 @@ package dump
import ( import (
"archive/tar" "archive/tar"
"bytes" "bytes"
"context"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -12,6 +14,8 @@ import (
"time" "time"
"github.com/restic/restic/internal/fs" "github.com/restic/restic/internal/fs"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
) )
func TestWriteTar(t *testing.T) { func TestWriteTar(t *testing.T) {
@ -112,3 +116,29 @@ func checkTar(t *testing.T, testDir string, srcTar *bytes.Buffer) error {
return nil 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)
}