Commit c991d2ab authored by Joe Tsai's avatar Joe Tsai Committed by Joe Tsai

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 <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 289a8719
...@@ -121,9 +121,15 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error { ...@@ -121,9 +121,15 @@ func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
needsPaxHeader := paxKeyword != paxNone && len(s) > len(b) || !isASCII(s) needsPaxHeader := paxKeyword != paxNone && len(s) > len(b) || !isASCII(s)
if needsPaxHeader { if needsPaxHeader {
paxHeaders[paxKeyword] = s 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) { var formatNumeric = func(b []byte, x int64, paxKeyword string) {
// Try octal first. // Try octal first.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment