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/zip: unexpected EOF #11144

Closed
dvyukov opened this issue Jun 10, 2015 · 5 comments
Closed

archive/zip: unexpected EOF #11144

dvyukov opened this issue Jun 10, 2015 · 5 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented Jun 10, 2015

The following program fails with the panic:

package main

import (
    "archive/zip"
    "bytes"
    "io/ioutil"
)

func main() {
    headers := []zip.FileHeader{
        {Name:"0", Method:8},
        {Name:"1", Method:8},
    }
    contents := [][]byte{
        []byte("a"),
        []byte("abcdefgh01234567890"),
    }
    buf := new(bytes.Buffer)
    w := zip.NewWriter(buf)
    for i, h := range headers {
        w1, err := w.CreateHeader(&h)
        if err != nil {
            panic(err)
        }
        _, err = w1.Write(contents[i])
        if err != nil {
            panic(err)
        }
    }
    err := w.Close()
    if err != nil {
        panic(err)
    }

    z1, err := zip.NewReader(bytes.NewReader(buf.Bytes()), int64(len(buf.Bytes())))
    if err != nil {
        panic(err)
    }
    var headers1 []zip.FileHeader
    var contents1 [][]byte
    for _, f := range z1.File {
        r, err := f.Open()
        if err != nil {
            panic(err)
        }
        c, err := ioutil.ReadAll(r)
        if err != nil {
            panic(err)
        }
        headers1 = append(headers1, f.FileHeader)
        contents1 = append(contents1, c)
        r.Close()
    }
}
panic: unexpected EOF

goroutine 1 [running]:
main.main()
    zip.go:48 +0x8f8

go version devel +b0532a9 Mon Jun 8 05:13:15 2015 +0000 linux/amd64

@dvyukov
Copy link
Member Author

dvyukov commented Jun 10, 2015

Oh, I see that CreateHeader retains the &h pointer passed to it. As the result all files in the archive share the same header. This explains everything.
But it is quite confusing and at least must be documented.

@adg adg assigned adg and unassigned bradfitz Jun 10, 2015
@dvyukov
Copy link
Member Author

dvyukov commented Jun 10, 2015

This user bug has quite obscure failure mode that is discovered only during reading. Writing finishes successfully producing a corrupted archive. So probably it makes sense to diagnose this misuse. Note that we don't need to remember/compare all header pointers for this, checking only the previous pointer would be enough.

@bradfitz
Copy link
Contributor

Sure, but I get to take your go-fuzz trophy back.

@dvyukov
Copy link
Member Author

dvyukov commented Jun 10, 2015

Well, this is discovered due to go-fuzz, one way or another :)

@gopherbot
Copy link

CL https://golang.org/cl/10883 mentions this issue.

@mikioh mikioh added this to the Go1.5 milestone Jun 11, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
@rsc rsc unassigned adg Jun 23, 2022
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

5 participants