]> Cypherpunks repositories - gostls13.git/commitdiff
archive/tar: Fix bug preventing untar
authorGuillaume J. Charmes <guillaume@charmes.net>
Wed, 14 May 2014 17:15:43 +0000 (10:15 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 14 May 2014 17:15:43 +0000 (10:15 -0700)
Do not use ustar format if we need the GNU one.
Change \000 to \x00 for consistency
Check for "ustar\x00" instead of "ustar\x00\x00" for conistency with tar
and compatiblity with archive generated with older code (which was ustar\x00\x20\x00)
Add test for long name + big file.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/99050043

src/pkg/archive/tar/reader.go
src/pkg/archive/tar/testdata/writer-big-long.tar [new file with mode: 0644]
src/pkg/archive/tar/writer.go
src/pkg/archive/tar/writer_test.go

index d15e12079240da7ae0deca40d5ae6a2e5e6053eb..e6ac538aad8dcac492ae73aaa5038a94dc9fa723 100644 (file)
@@ -468,14 +468,14 @@ func (tr *Reader) readHeader() *Header {
        // so its magic bytes, like the rest of the block, are NULs.
        magic := string(s.next(8)) // contains version field as well.
        var format string
-       switch magic {
-       case "ustar\x0000": // POSIX tar (1003.1-1988)
+       switch {
+       case magic[:6] == "ustar\x00": // POSIX tar (1003.1-1988)
                if string(header[508:512]) == "tar\x00" {
                        format = "star"
                } else {
                        format = "posix"
                }
-       case "ustar  \x00": // old GNU tar
+       case magic == "ustar  \x00": // old GNU tar
                format = "gnu"
        }
 
diff --git a/src/pkg/archive/tar/testdata/writer-big-long.tar b/src/pkg/archive/tar/testdata/writer-big-long.tar
new file mode 100644 (file)
index 0000000..5960ee8
Binary files /dev/null and b/src/pkg/archive/tar/testdata/writer-big-long.tar differ
index 9ee94992970eca4bf7b8ec7770616e0ef4767d45..6eff6f6f84d8eaa903b87c135ec4f5f6684b4667 100644 (file)
@@ -218,8 +218,8 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
                                tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
 
                                // Use the ustar magic if we used ustar long names.
-                               if len(prefix) > 0 {
-                                       copy(header[257:265], []byte("ustar\000"))
+                               if len(prefix) > 0 && !tw.usedBinary {
+                                       copy(header[257:265], []byte("ustar\x00"))
                                }
                        }
                }
index 2b9ea658db479193aebd5e3f391ea361b2869e79..512fab1a6f1c18496f7ca834dff08347c814f0cf 100644 (file)
@@ -103,6 +103,29 @@ var writerTests = []*writerTest{
                        },
                },
        },
+       // The truncated test file was produced using these commands:
+       //   dd if=/dev/zero bs=1048576 count=16384 > (longname/)*15 /16gig.txt
+       //   tar -b 1 -c -f- (longname/)*15 /16gig.txt | dd bs=512 count=8 > writer-big-long.tar
+       {
+               file: "testdata/writer-big-long.tar",
+               entries: []*writerTestEntry{
+                       {
+                               header: &Header{
+                                       Name:     strings.Repeat("longname/", 15) + "16gig.txt",
+                                       Mode:     0644,
+                                       Uid:      1000,
+                                       Gid:      1000,
+                                       Size:     16 << 30,
+                                       ModTime:  time.Unix(1399583047, 0),
+                                       Typeflag: '0',
+                                       Uname:    "guillaume",
+                                       Gname:    "guillaume",
+                               },
+                               // fake contents
+                               contents: strings.Repeat("\x00", 4<<10),
+                       },
+               },
+       },
        // This file was produced using gnu tar 1.17
        // gnutar  -b 4 --format=ustar (longname/)*15 + file.txt
        {