Skip to content

Commit 40bdcbb

Browse files
AlexanderYastrebovgopherbot
authored andcommitted
archive/zip: don't read directories containing file data
Fixes #54801 Change-Id: I3d03516792975ddb09835b2621c57e12e7cbad35 GitHub-Last-Rev: 4faa7e1 GitHub-Pull-Request: #56714 Reviewed-on: https://go-review.googlesource.com/c/go/+/449955 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Joedian Reid <[email protected]>
1 parent c55d184 commit 40bdcbb

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

src/archive/zip/reader.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ func (f *File) Open() (io.ReadCloser, error) {
197197
if err != nil {
198198
return nil, err
199199
}
200+
if strings.HasSuffix(f.Name, "/") {
201+
if f.CompressedSize64 != 0 || f.hasDataDescriptor() {
202+
return &dirReader{ErrFormat}, nil
203+
} else {
204+
return &dirReader{io.EOF}, nil
205+
}
206+
}
200207
size := int64(f.CompressedSize64)
201208
r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
202209
dcomp := f.zip.decompressor(f.Method)
@@ -228,6 +235,18 @@ func (f *File) OpenRaw() (io.Reader, error) {
228235
return r, nil
229236
}
230237

238+
type dirReader struct {
239+
err error
240+
}
241+
242+
func (r *dirReader) Read([]byte) (int, error) {
243+
return 0, r.err
244+
}
245+
246+
func (r *dirReader) Close() error {
247+
return nil
248+
}
249+
231250
type checksumReader struct {
232251
rc io.ReadCloser
233252
hash hash.Hash32

src/archive/zip/reader_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,3 +1554,33 @@ func TestUnderSize(t *testing.T) {
15541554
})
15551555
}
15561556
}
1557+
1558+
func TestIssue54801(t *testing.T) {
1559+
for _, input := range []string{"testdata/readme.zip", "testdata/dd.zip"} {
1560+
z, err := OpenReader(input)
1561+
if err != nil {
1562+
t.Fatal(err)
1563+
}
1564+
defer z.Close()
1565+
1566+
for _, f := range z.File {
1567+
// Make file a directory
1568+
f.Name += "/"
1569+
1570+
t.Run(f.Name, func(t *testing.T) {
1571+
t.Logf("CompressedSize64: %d, Flags: %#x", f.CompressedSize64, f.Flags)
1572+
1573+
rd, err := f.Open()
1574+
if err != nil {
1575+
t.Fatal(err)
1576+
}
1577+
defer rd.Close()
1578+
1579+
n, got := io.Copy(io.Discard, rd)
1580+
if n != 0 || got != ErrFormat {
1581+
t.Fatalf("Error mismatch, got: %d, %v, want: %v", n, got, ErrFormat)
1582+
}
1583+
})
1584+
}
1585+
}
1586+
}

0 commit comments

Comments
 (0)