hdr.Typeflag = v7.TypeFlag()[0]
        hdr.Linkname = p.parseString(v7.LinkName())
 
+       // The atime and ctime fields are often left unused. Some versions of Go
+       // had a bug in the tar.Writer where it would output an invalid tar file
+       // in certain rare situations because the logic incorrectly believed that
+       // the old GNU format had a prefix field. This is wrong and leads to
+       // an outputted file that actually mangles the atime and ctime fields.
+       //
+       // In order to continue reading tar files created by a buggy writer, we
+       // try to parse the atime and ctime fields, but just return the zero value
+       // of time.Time when we cannot parse them.
+       //
+       // See https://golang.org/issues/12594
+       tryParseTime := func(b []byte) time.Time {
+               var p parser
+               n := p.parseNumeric(b)
+               if b[0] != 0x00 && p.err == nil {
+                       return time.Unix(n, 0)
+               }
+               return time.Time{}
+       }
+
        // Unpack format specific fields.
        if format > formatV7 {
                ustar := tr.blk.USTAR()
 
                var prefix string
                switch format {
-               case formatUSTAR, formatGNU:
-                       // TODO(dsnet): Do not use the prefix field for the GNU format!
-                       // See golang.org/issues/12594
+               case formatUSTAR:
                        ustar := tr.blk.USTAR()
                        prefix = p.parseString(ustar.Prefix())
                case formatSTAR:
                        prefix = p.parseString(star.Prefix())
                        hdr.AccessTime = time.Unix(p.parseNumeric(star.AccessTime()), 0)
                        hdr.ChangeTime = time.Unix(p.parseNumeric(star.ChangeTime()), 0)
+               case formatGNU:
+                       gnu := tr.blk.GNU()
+                       hdr.AccessTime = tryParseTime(gnu.AccessTime())
+                       hdr.ChangeTime = tryParseTime(gnu.ChangeTime())
                }
                if len(prefix) > 0 {
                        hdr.Name = prefix + "/" + hdr.Name
 
                        },
                },
        },
+       {
+               // GNU tar file with atime and ctime fields set.
+               // Created with the GNU tar v1.27.1.
+               //      tar --incremental -S -cvf gnu-incremental.tar test2
+               file: "testdata/gnu-incremental.tar",
+               headers: []*Header{
+                       {
+                               Name:       "test2/",
+                               Mode:       16877,
+                               Uid:        1000,
+                               Gid:        1000,
+                               Size:       14,
+                               ModTime:    time.Unix(1441973427, 0),
+                               Typeflag:   'D',
+                               Uname:      "rawr",
+                               Gname:      "dsnet",
+                               AccessTime: time.Unix(1441974501, 0),
+                               ChangeTime: time.Unix(1441973436, 0),
+                       },
+                       {
+                               Name:       "test2/foo",
+                               Mode:       33188,
+                               Uid:        1000,
+                               Gid:        1000,
+                               Size:       64,
+                               ModTime:    time.Unix(1441973363, 0),
+                               Typeflag:   '0',
+                               Uname:      "rawr",
+                               Gname:      "dsnet",
+                               AccessTime: time.Unix(1441974501, 0),
+                               ChangeTime: time.Unix(1441973436, 0),
+                       },
+                       {
+                               Name:       "test2/sparse",
+                               Mode:       33188,
+                               Uid:        1000,
+                               Gid:        1000,
+                               Size:       536870912,
+                               ModTime:    time.Unix(1441973427, 0),
+                               Typeflag:   'S',
+                               Uname:      "rawr",
+                               Gname:      "dsnet",
+                               AccessTime: time.Unix(1441991948, 0),
+                               ChangeTime: time.Unix(1441973436, 0),
+                       },
+               },
+       },
        {
                // Matches the behavior of GNU and BSD tar utilities.
                file: "testdata/pax-multi-hdrs.tar",