Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

archive/tar: long paths produce incompatible output with dpkg #22675

Closed
jboelter opened this issue Nov 12, 2017 · 2 comments
Closed

archive/tar: long paths produce incompatible output with dpkg #22675

jboelter opened this issue Nov 12, 2017 · 2 comments

Comments

@jboelter
Copy link

What version of Go are you using (go version)?

1.5.4 - ok
did not try interim releases to narrow it down
1.9.2 - fails

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

The latest version of the archive/tar package in 1.9.2 produces output that is incompatible with dpkg as exposed by the godeb tool. See this related bug - niemeyer/godeb#29

Building the godeb tool with 1.5.4 works (use the pull request w/ the fixes for the new download URLs), building with 1.9.2 fails.

@dsnet
Copy link
Member

dsnet commented Nov 12, 2017

The cause of this issue is that dpkg expects tar archives to be the GNU format, and does not understand the PAX format. In Go1.8 (and in Go1.9), I disabled path prefix splitting because the behavior was entirely buggy. This prevented the tar package from being able to use the USTAR format (which dpkg still understands), but forced it to use PAX to represent the longer file names. The inability to have control over the output format is the root issue here since both GNU and PAX are popular variants of tar.

For this reason, I filed #18710. In Go1.10, you will be able to explicitly specify that the output format is GNU, which will make dpkg happy again.

@jboelter
Copy link
Author

Confirmed the tip works to translate from PAX -> GNU (at least for this use in the godeb tool). Thanks @dsnet

in := tar.NewReader(...)
out := tar.NewWriter(...)
defer out.Close()
for {
	h, err := in.Next()
	if err == io.EOF { break }
	h.Format = tar.FormatGNU
	h.PAXRecords = nil
	out.WriteHeader(h)
	if h.Typeflag == tar.TypeDir { continue }
	w, err := io.Copy(out, in)
}

@golang golang locked and limited conversation to collaborators Nov 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants