archive/tar: eats file data
dvyukov opened this issue · 4 comments
dvyukov commented
The following program fails with the panic:
package main
import (
"archive/tar"
"bytes"
"fmt"
"io"
"io/ioutil"
)
func main() {
data := []byte("aaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"0100640\x000374534\x000011" +
"610\x0000000000007\x001253" +
"1145371\x00010572\x0000\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ust" +
"ar \x00dvyukov\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eng" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000000")
t := tar.NewReader(bytes.NewReader(data))
var headers []*tar.Header
var contents [][]byte
for {
hdr, err := t.Next()
if err == io.EOF {
break
}
if err != nil {
return
}
fdata, err := ioutil.ReadAll(t)
if err != nil {
return
}
hdr1 := *hdr
headers = append(headers, &hdr1)
contents = append(contents, fdata)
}
buf := new(bytes.Buffer)
w := tar.NewWriter(buf)
for i, hdr := range headers {
err := w.WriteHeader(hdr)
if err != nil {
panic(err)
}
_, err = w.Write(contents[i])
if err != nil {
panic(err)
}
}
err := w.Close()
if err != nil {
panic(err)
}
t1 := tar.NewReader(buf)
for i := 0; ; i++ {
_, err := t1.Next()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
fdata, err := ioutil.ReadAll(t)
if err != nil {
panic(err)
}
if !bytes.Equal(fdata, contents[i]) {
fmt.Printf("got : %q\n", fdata)
fmt.Printf("want: %q\n", contents[i])
panic("data differs")
}
}
}
got : ""
want: "0000000"
panic: data differs
That is, file data is lost after packing/unpacking.
go version devel +b0532a9 Mon Jun 8 05:13:15 2015 +0000 linux/amd64
dadkins commented
There is a type in this test program. Replace
fdata, err := ioutil.ReadAll(t)
with
fdata, err := ioutil.ReadAll(t1)
and the test passes.
If there is any issue here, it's that the second call to ioutil.ReadAll(t) succeeds and returns 512 bytes. How is that possible? Did the underlying Reader somehow reset?
dadkins commented
s/type/typo/
And I was wrong in my initial comment. The second call to ioutil.RealAll(t) returns [], nil as expected at EOF.
There is no bug here.