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:
parent
09ed0f6805
commit
816deacc70
@ -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))
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user