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

Tar.NewReader strange behavior #38286

Closed
vieirin opened this issue Apr 7, 2020 · 3 comments
Closed

Tar.NewReader strange behavior #38286

vieirin opened this issue Apr 7, 2020 · 3 comments

Comments

@vieirin
Copy link

vieirin commented Apr 7, 2020

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

$ go version
     go version go1.14.1 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build020686916=/tmp/go-build -gno-record-gcc-switches"
docker tag: golang:1.14.1-alpine3.11

What did you do?

I'm trying to return a tar.Reader from a function, but its Read() method has a strange behavior
if you write a tar using tar.Writer interface it points to a buffer, trying to create a reader with tar.NewReader(buf) gives the correct list of files from tr.Next() method, but its Read() method always points to end of buffer
Here's an example:
https://play.golang.org/p/GnCF_B1TWFE
here error is EOF, although we can iterate over tr.Next() subsequently (aren't readers streams?)

We could make sure this isn't about allocation using ioutil.ReadAll():
https://play.golang.org/p/DLFn_J0pgzN
here error is nil, but the []byte is empty

Things get a little more weird if you edit first example adding a Next() call before calling tr.Read()
https://play.golang.org/p/RYJY1cz02Ms
Now []byte is not empty but instead has the first file content, and read error: EOF 🤯

What did you expect to see?

A filled []byte when read is called

What did you see instead?

An empty []byte in return

@rasky
Copy link
Member

rasky commented Apr 7, 2020

After calling tar.NewReader, you need to immediately call Next to advance to the first file (and get any error occurred while parsing the header of the first file -- eg: when reading a file which is not a tar). This first Next call parses the tar header and decodes information on the first file, so that it is then possible to start reading the first file.

This is (lightly) documented on type Reader when it says: Reader.Next advances to the next file in the archive (including the first), and then Reader can be treated as an io.Reader to access the file's data..

So this behavior is expected.

@rasky rasky closed this as completed Apr 7, 2020
@vieirin
Copy link
Author

vieirin commented Apr 7, 2020

Well, I still get just the first content from reader when advancing the pointer with Next()
https://play.golang.org/p/od2FDjWwrbo
Is that expected?

@rasky
Copy link
Member

rasky commented Apr 7, 2020

Yes. After you read the first file, call Next again to go to the second one. This is all documented and the examples in the documentations show you how to decode all the contents using a loop.

@golang golang locked and limited conversation to collaborators Apr 7, 2021
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