From a140971c21a61520f41146f4b5ff039c97e57219 Mon Sep 17 00:00:00 2001 From: Maximilian Moehl Date: Wed, 24 Dec 2025 13:00:06 +0100 Subject: [PATCH] Add support for extracting xattrs on unix When extended file attributes are set on a file in the archive, try to preserve them on extraction but do not fail when the user does not have permission to set them or if they are not supported. This should prevent existing usages from breaking while also enabling users to preserve extended file attributes. --- extractor/tgz_extractor.go | 6 +++++- extractor/xattr_unix.go | 29 +++++++++++++++++++++++++++++ extractor/xattr_windows.go | 9 +++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 extractor/xattr_unix.go create mode 100644 extractor/xattr_windows.go diff --git a/extractor/tgz_extractor.go b/extractor/tgz_extractor.go index 6522e31..fa8765b 100644 --- a/extractor/tgz_extractor.go +++ b/extractor/tgz_extractor.go @@ -105,5 +105,9 @@ func extractTarArchiveFile(header *tar.Header, dest string, input io.Reader) err defer fileCopy.Close() _, err = io.Copy(fileCopy, input) - return err + if err != nil { + return err + } + + return setXattrsFromTar(filePath, header) } diff --git a/extractor/xattr_unix.go b/extractor/xattr_unix.go new file mode 100644 index 0000000..68310d5 --- /dev/null +++ b/extractor/xattr_unix.go @@ -0,0 +1,29 @@ +//go:build unix + +package extractor + +import ( + "archive/tar" + "errors" + "strings" + "syscall" + + "golang.org/x/sys/unix" +) + +func setXattrsFromTar(path string, hdr *tar.Header) (err error) { + const paxSchilyXattr = "SCHILY.xattr." + + for key, value := range hdr.PAXRecords { + if !strings.HasPrefix(key, paxSchilyXattr) { + continue + } + + err = unix.Lsetxattr(path, key[len(paxSchilyXattr):], []byte(value), 0) + if err != nil && !errors.Is(err, syscall.ENOTSUP) && !errors.Is(err, syscall.EPERM) { + return err + } + } + + return nil +} diff --git a/extractor/xattr_windows.go b/extractor/xattr_windows.go new file mode 100644 index 0000000..f5bfba9 --- /dev/null +++ b/extractor/xattr_windows.go @@ -0,0 +1,9 @@ +//go:build windows + +package extractor + +import "archive/tar" + +func setXattrsFromTar(_ string, _ *tar.Header) error { + return nil +}