1
0
mirror of https://github.com/golang/go synced 2024-11-17 16:14:42 -07:00

archive/zip: fix Writer to validate file

The ZIP format uses uint16 to contain the length of the file name and
the length of the Extra section. This change verifies that the length
of these fields fit in an uint16 prior to writing the ZIP file. If not,
an error is returned.

Fixes #17402

Change-Id: Ief9a864d2fe16b89ddb9917838283b801a2c58a4
Reviewed-on: https://go-review.googlesource.com/50250
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Audrey Lim 2017-07-15 12:33:06 -06:00 committed by Joe Tsai
parent 09ed0f6805
commit 816deacc70
2 changed files with 51 additions and 0 deletions

View File

@ -14,6 +14,11 @@ import (
"unicode/utf8"
)
var (
errLongName = errors.New("zip: FileHeader.Name too long")
errLongExtra = errors.New("zip: FileHeader.Extra too long")
)
// Writer implements a zip file writer.
type Writer struct {
cw *countWriter
@ -273,6 +278,14 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
}
func writeHeader(w io.Writer, h *FileHeader) error {
const maxUint16 = 1<<16 - 1
if len(h.Name) > maxUint16 {
return errLongName
}
if len(h.Extra) > maxUint16 {
return errLongExtra
}
var buf [fileHeaderLen]byte
b := writeBuf(buf[:])
b.uint32(uint32(fileHeaderSignature))

View File

@ -650,6 +650,44 @@ func TestHeaderTooShort(t *testing.T) {
testValidHeader(&h, t)
}
func TestHeaderTooLongErr(t *testing.T) {
var headerTests = []struct {
name string
extra []byte
wanterr error
}{
{
name: strings.Repeat("x", 1<<16),
extra: []byte{},
wanterr: errLongName,
},
{
name: "long_extra",
extra: bytes.Repeat([]byte{0xff}, 1<<16),
wanterr: errLongExtra,
},
}
// write a zip file
buf := new(bytes.Buffer)
w := NewWriter(buf)
for _, test := range headerTests {
h := &FileHeader{
Name: test.name,
Extra: test.extra,
}
_, err := w.CreateHeader(h)
if err != test.wanterr {
t.Errorf("error=%v, want %v", err, test.wanterr)
}
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
}
func TestHeaderIgnoredSize(t *testing.T) {
h := FileHeader{
Name: "foo.txt",