From: Joe Tsai Date: Wed, 28 Jun 2017 00:30:39 +0000 (-0700) Subject: archive/tar: use best effort at writing USTAR header X-Git-Tag: go1.9rc1~149 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c991d2ab14496789146560608c5756d5d83b35f6;p=gostls13.git archive/tar: use best effort at writing USTAR header Prior to this change, if the Writer needed to use the PAX format, it would output a USTAR header with an empty name. This should be okay since the PAX specification dictates that the PAX record for "path" should override the semantic meaning of any of the old USTAR fields. Unfortunately, the implementation of tar on OpenBSD 6.1 is too strict with their handling of PAX files such that they check for the validity of this bogus field even though the PAX header is present. To allow Go's Writer output be parsible by OpenBSD's tar utility, we write a best-effort (ASCII-only and truncated) version of the original file name. Note that this still fails in some edge-cases (for example, a Chinese filename containing all non-ASCII characters). OpenBSD should really relax their checking, as you honestly can't always expect a sensible path to be generated when USTAR cannot handle the original path. Fixes #20707 Change-Id: Id7d77349023d2152d7291d582cd050b6681760e4 Reviewed-on: https://go-review.googlesource.com/46914 Run-TryBot: Joe Tsai TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/archive/tar/testdata/ustar.issue12594.tar b/src/archive/tar/testdata/ustar.issue12594.tar index c7910ae9f4..50fcd00976 100644 Binary files a/src/archive/tar/testdata/ustar.issue12594.tar and b/src/archive/tar/testdata/ustar.issue12594.tar differ diff --git a/src/archive/tar/testdata/writer-big-long.tar b/src/archive/tar/testdata/writer-big-long.tar index 52bd748f3b..ea9bfa88bb 100644 Binary files a/src/archive/tar/testdata/writer-big-long.tar and b/src/archive/tar/testdata/writer-big-long.tar differ diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go index 596fb8b9e1..c51c243a8b 100644 --- a/src/archive/tar/writer.go +++ b/src/archive/tar/writer.go @@ -121,9 +121,15 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error { needsPaxHeader := paxKeyword != paxNone && len(s) > len(b) || !isASCII(s) if needsPaxHeader { paxHeaders[paxKeyword] = s - return } - f.formatString(b, s) + + // Write string in a best-effort manner to satisfy readers that expect + // the field to be non-empty. + s = toASCII(s) + if len(s) > len(b) { + s = s[:len(b)] + } + f.formatString(b, s) // Should never error } var formatNumeric = func(b []byte, x int64, paxKeyword string) { // Try octal first.