summaryrefslogtreecommitdiff
path: root/debian/patches/add-tar-xattr-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/add-tar-xattr-support.patch')
-rw-r--r--debian/patches/add-tar-xattr-support.patch175
1 files changed, 175 insertions, 0 deletions
diff --git a/debian/patches/add-tar-xattr-support.patch b/debian/patches/add-tar-xattr-support.patch
new file mode 100644
index 000000000..904e0110d
--- /dev/null
+++ b/debian/patches/add-tar-xattr-support.patch
@@ -0,0 +1,175 @@
+--- a/src/pkg/archive/tar/common.go
++++ b/src/pkg/archive/tar/common.go
+@@ -57,6 +57,7 @@
+ Devminor int64 // minor number of character or block device
+ AccessTime time.Time // access time
+ ChangeTime time.Time // status change time
++ Xattrs map[string]string
+ }
+
+ // File name constants from the tar spec.
+@@ -189,6 +190,7 @@
+ paxSize = "size"
+ paxUid = "uid"
+ paxUname = "uname"
++ paxXattr = "SCHILY.xattr."
+ paxNone = ""
+ )
+
+--- a/src/pkg/archive/tar/reader.go
++++ b/src/pkg/archive/tar/reader.go
+@@ -139,8 +139,14 @@
+ return err
+ }
+ hdr.Size = int64(size)
++ default:
++ if strings.HasPrefix(k, paxXattr) {
++ if hdr.Xattrs == nil {
++ hdr.Xattrs = make(map[string]string)
++ }
++ hdr.Xattrs[k[len(paxXattr):]] = v
++ }
+ }
+-
+ }
+ return nil
+ }
+--- a/src/pkg/archive/tar/reader_test.go
++++ b/src/pkg/archive/tar/reader_test.go
+@@ -161,6 +161,46 @@
+ },
+ },
+ },
++ {
++ file: "testdata/xattrs.tar",
++ headers: []*Header{
++ {
++ Name: "small.txt",
++ Mode: 0644,
++ Uid: 1000,
++ Gid: 10,
++ Size: 5,
++ ModTime: time.Unix(1386065770, 448252320),
++ Typeflag: '0',
++ Uname: "alex",
++ Gname: "wheel",
++ AccessTime: time.Unix(1389782991, 419875220),
++ ChangeTime: time.Unix(1389782956, 794414986),
++ Xattrs: map[string]string{
++ "user.key": "value",
++ "user.key2": "value2",
++ // Interestingly, selinux encodes the terminating null inside the xattr
++ "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
++ },
++ },
++ {
++ Name: "small2.txt",
++ Mode: 0644,
++ Uid: 1000,
++ Gid: 10,
++ Size: 11,
++ ModTime: time.Unix(1386065770, 449252304),
++ Typeflag: '0',
++ Uname: "alex",
++ Gname: "wheel",
++ AccessTime: time.Unix(1389782991, 419875220),
++ ChangeTime: time.Unix(1386065770, 449252304),
++ Xattrs: map[string]string{
++ "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
++ },
++ },
++ },
++ },
+ }
+
+ func TestReader(t *testing.T) {
+@@ -180,7 +220,7 @@
+ f.Close()
+ continue testLoop
+ }
+- if *hdr != *header {
++ if !reflect.DeepEqual(*hdr, *header) {
+ t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
+ i, j, *hdr, *header)
+ }
+@@ -253,7 +293,7 @@
+ }
+
+ // check the header
+- if *hdr != *headers[nread] {
++ if !reflect.DeepEqual(*hdr, *headers[nread]) {
+ t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
+ *hdr, headers[nread])
+ }
+Binary files /dev/null and b/src/pkg/archive/tar/testdata/xattrs.tar differ
+--- a/src/pkg/archive/tar/writer.go
++++ b/src/pkg/archive/tar/writer.go
+@@ -236,6 +236,12 @@
+ return tw.err
+ }
+
++ if allowPax {
++ for k, v := range hdr.Xattrs {
++ paxHeaders[paxXattr+k] = v
++ }
++ }
++
+ if len(paxHeaders) > 0 {
+ if !allowPax {
+ return errInvalidHeader
+--- a/src/pkg/archive/tar/writer_test.go
++++ b/src/pkg/archive/tar/writer_test.go
+@@ -10,6 +10,7 @@
+ "io"
+ "io/ioutil"
+ "os"
++ "reflect"
+ "strings"
+ "testing"
+ "testing/iotest"
+@@ -338,6 +339,45 @@
+ }
+ }
+
++func TestPaxXattrs(t *testing.T) {
++ xattrs := map[string]string{
++ "user.key": "value",
++ }
++
++ // Create an archive with an xattr
++ fileinfo, err := os.Stat("testdata/small.txt")
++ if err != nil {
++ t.Fatal(err)
++ }
++ hdr, err := FileInfoHeader(fileinfo, "")
++ if err != nil {
++ t.Fatalf("os.Stat: %v", err)
++ }
++ contents := "Kilts"
++ hdr.Xattrs = xattrs
++ var buf bytes.Buffer
++ writer := NewWriter(&buf)
++ if err := writer.WriteHeader(hdr); err != nil {
++ t.Fatal(err)
++ }
++ if _, err = writer.Write([]byte(contents)); err != nil {
++ t.Fatal(err)
++ }
++ if err := writer.Close(); err != nil {
++ t.Fatal(err)
++ }
++ // Test that we can get the xattrs back out of the archive.
++ reader := NewReader(&buf)
++ hdr, err = reader.Next()
++ if err != nil {
++ t.Fatal(err)
++ }
++ if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
++ t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
++ hdr.Xattrs, xattrs)
++ }
++}
++
+ func TestPAXHeader(t *testing.T) {
+ medName := strings.Repeat("CD", 50)
+ longName := strings.Repeat("AB", 100)