From c991d2ab14496789146560608c5756d5d83b35f6 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Tue, 27 Jun 2017 17:30:39 -0700 Subject: [PATCH] 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 --- src/archive/tar/testdata/ustar.issue12594.tar | Bin 3072 -> 3072 bytes src/archive/tar/testdata/writer-big-long.tar | Bin 4096 -> 4096 bytes src/archive/tar/writer.go | 10 ++++++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/archive/tar/testdata/ustar.issue12594.tar b/src/archive/tar/testdata/ustar.issue12594.tar index c7910ae9f43b54e32b9facf34c9e96a03626adea..50fcd00976066625be6d9aef68aa7b24a6a99c29 100644 GIT binary patch delta 35 rcmZpWXpmUIGC7dRexkkR 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. -- 2.50.0