Commit 8cd00a52 authored by Diogo Pinela's avatar Diogo Pinela Committed by Joe Tsai

archive/zip: prevent writing data for a directory

When creating a directory, Writer.Create now returns a dummy
io.Writer that always returns an error on Write.

Fixes #24043

Change-Id: I7792f54440d45d22d0aa174cba5015ed5fab1c5c
Reviewed-on: https://go-review.googlesource.com/108615Reviewed-by: default avatarJoe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 2191c3a4
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"hash" "hash"
"hash/crc32" "hash/crc32"
"io" "io"
"strings"
"unicode/utf8" "unicode/utf8"
) )
...@@ -320,35 +321,43 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) { ...@@ -320,35 +321,43 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
fh.Extra = append(fh.Extra, mbuf[:]...) fh.Extra = append(fh.Extra, mbuf[:]...)
} }
fw := &fileWriter{ var (
zipw: w.cw, ow io.Writer
compCount: &countWriter{w: w.cw}, fw *fileWriter
crc32: crc32.NewIEEE(), )
}
comp := w.compressor(fh.Method)
if comp == nil {
return nil, ErrAlgorithm
}
var err error
fw.comp, err = comp(fw.compCount)
if err != nil {
return nil, err
}
fw.rawCount = &countWriter{w: fw.comp}
h := &header{ h := &header{
FileHeader: fh, FileHeader: fh,
offset: uint64(w.cw.count), offset: uint64(w.cw.count),
} }
w.dir = append(w.dir, h)
fw.header = h
if strings.HasSuffix(fh.Name, "/") {
ow = dirWriter{}
} else {
fw = &fileWriter{
zipw: w.cw,
compCount: &countWriter{w: w.cw},
crc32: crc32.NewIEEE(),
}
comp := w.compressor(fh.Method)
if comp == nil {
return nil, ErrAlgorithm
}
var err error
fw.comp, err = comp(fw.compCount)
if err != nil {
return nil, err
}
fw.rawCount = &countWriter{w: fw.comp}
fw.header = h
ow = fw
}
w.dir = append(w.dir, h)
if err := writeHeader(w.cw, fh); err != nil { if err := writeHeader(w.cw, fh); err != nil {
return nil, err return nil, err
} }
// If we're creating a directory, fw is nil.
w.last = fw w.last = fw
return fw, nil return ow, nil
} }
func writeHeader(w io.Writer, h *FileHeader) error { func writeHeader(w io.Writer, h *FileHeader) error {
...@@ -401,6 +410,12 @@ func (w *Writer) compressor(method uint16) Compressor { ...@@ -401,6 +410,12 @@ func (w *Writer) compressor(method uint16) Compressor {
return comp return comp
} }
type dirWriter struct{}
func (dirWriter) Write([]byte) (int, error) {
return 0, errors.New("zip: write to directory")
}
type fileWriter struct { type fileWriter struct {
*header *header
zipw io.Writer zipw io.Writer
......
...@@ -299,6 +299,17 @@ func TestWriterFlush(t *testing.T) { ...@@ -299,6 +299,17 @@ func TestWriterFlush(t *testing.T) {
} }
} }
func TestWriterDir(t *testing.T) {
w := NewWriter(ioutil.Discard)
dw, err := w.Create("dir/")
if err != nil {
t.Fatal(err)
}
if _, err := dw.Write([]byte("hello")); err == nil {
t.Error("Write to directory: got nil error, want non-nil")
}
}
func testCreate(t *testing.T, w *Writer, wt *WriteTest) { func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
header := &FileHeader{ header := &FileHeader{
Name: wt.Name, Name: wt.Name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment