restore: remove unexpected xattrs from files

This commit is contained in:
Michael Eischer 2024-06-13 22:21:00 +02:00
parent ebbd4e26d7
commit 4d6042fe95
2 changed files with 66 additions and 0 deletions

View file

@ -40,6 +40,11 @@ func setxattr(path, name string, data []byte) error {
return handleXattrErr(xattr.LSet(path, name, data))
}
// removexattr removes the attribute name from path.
func removexattr(path, name string) error {
return handleXattrErr(xattr.LRemove(path, name))
}
func handleXattrErr(err error) error {
switch e := err.(type) {
case nil:
@ -70,12 +75,29 @@ func (node *Node) fillGenericAttributes(_ string, _ os.FileInfo, _ *statT) (allo
}
func (node Node) restoreExtendedAttributes(path string) error {
expectedAttrs := map[string]struct{}{}
for _, attr := range node.ExtendedAttributes {
err := setxattr(path, attr.Name, attr.Value)
if err != nil {
return err
}
expectedAttrs[attr.Name] = struct{}{}
}
// remove unexpected xattrs
xattrs, err := listxattr(path)
if err != nil {
return err
}
for _, name := range xattrs {
if _, ok := expectedAttrs[name]; ok {
continue
}
if err := removexattr(path, name); err != nil {
return err
}
}
return nil
}

View file

@ -0,0 +1,44 @@
//go:build darwin || freebsd || linux || solaris || windows
// +build darwin freebsd linux solaris windows
package restic
import (
"os"
"path/filepath"
"testing"
rtest "github.com/restic/restic/internal/test"
)
func setAndVerifyXattr(t *testing.T, file string, attrs []ExtendedAttribute) {
node := Node{
ExtendedAttributes: attrs,
}
rtest.OK(t, node.restoreExtendedAttributes(file))
nodeActual := Node{}
rtest.OK(t, nodeActual.fillExtendedAttributes(file, false))
rtest.Assert(t, nodeActual.sameExtendedAttributes(node), "xattr mismatch got %v expected %v", nodeActual.ExtendedAttributes, node.ExtendedAttributes)
}
func TestOverwriteXattr(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "file")
rtest.OK(t, os.WriteFile(file, []byte("hello world"), 0o600))
setAndVerifyXattr(t, file, []ExtendedAttribute{
{
Name: "user.foo",
Value: []byte("bar"),
},
})
setAndVerifyXattr(t, file, []ExtendedAttribute{
{
Name: "user.other",
Value: []byte("some"),
},
})
}