From f565862abcceaf74c2266ba40f34c1b24c6f40c3 Mon Sep 17 00:00:00 2001 From: unclejack Date: Thu, 17 Jul 2014 08:54:26 +0300 Subject: [PATCH] archive/tar: update to fix writing of PAX headers Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) --- hack/vendor.sh | 2 +- .../p/go/src/pkg/archive/tar/writer.go | 15 ++++++-- .../p/go/src/pkg/archive/tar/writer_test.go | 35 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/hack/vendor.sh b/hack/vendor.sh index 93ecc8131e..4bb5970c02 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -55,7 +55,7 @@ clone hg code.google.com/p/gosqlite 74691fb6f837 # get Go tip's archive/tar, for xattr support and improved performance # TODO after Go 1.4 drops, bump our minimum supported version and drop this vendored dep -clone hg code.google.com/p/go 17404efd6b02 +clone hg code.google.com/p/go 1b17b3426e3c mv src/code.google.com/p/go/src/pkg/archive/tar tmp-tar rm -rf src/code.google.com/p/go mkdir -p src/code.google.com/p/go/src/pkg/archive diff --git a/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go b/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go index d107dbbb51..dafb2cabf3 100644 --- a/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go +++ b/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer.go @@ -39,7 +39,8 @@ type Writer struct { closed bool usedBinary bool // whether the binary numeric field extension was used preferPax bool // use pax header instead of binary numeric header - hdrBuff [blockSize]byte // buffer to use in writeHeader + hdrBuff [blockSize]byte // buffer to use in writeHeader when writing a regular header + paxHdrBuff [blockSize]byte // buffer to use in writeHeader when writing a pax header } // NewWriter creates a new Writer writing to w. @@ -161,7 +162,17 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error { // subsecond time resolution, but for now let's just capture // too long fields or non ascii characters - header := tw.hdrBuff[:] + var header []byte + + // We need to select which scratch buffer to use carefully, + // since this method is called recursively to write PAX headers. + // If allowPax is true, this is the non-recursive call, and we will use hdrBuff. + // If allowPax is false, we are being called by writePAXHeader, and hdrBuff is + // already being used by the non-recursive call, so we must use paxHdrBuff. + header = tw.hdrBuff[:] + if !allowPax { + header = tw.paxHdrBuff[:] + } copy(header, zeroBlock) s := slicer(header) diff --git a/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go b/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go index 512fab1a6f..5e42e322f9 100644 --- a/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go +++ b/vendor/src/code.google.com/p/go/src/pkg/archive/tar/writer_test.go @@ -454,3 +454,38 @@ func TestUSTARLongName(t *testing.T) { t.Fatal("Couldn't recover long name") } } + +func TestValidTypeflagWithPAXHeader(t *testing.T) { + var buffer bytes.Buffer + tw := NewWriter(&buffer) + + fileName := strings.Repeat("ab", 100) + + hdr := &Header{ + Name: fileName, + Size: 4, + Typeflag: 0, + } + if err := tw.WriteHeader(hdr); err != nil { + t.Fatalf("Failed to write header: %s", err) + } + if _, err := tw.Write([]byte("fooo")); err != nil { + t.Fatalf("Failed to write the file's data: %s", err) + } + tw.Close() + + tr := NewReader(&buffer) + + for { + header, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + t.Fatalf("Failed to read header: %s", err) + } + if header.Typeflag != 0 { + t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag) + } + } +}