]> Cypherpunks repositories - gostls13.git/commitdiff
archive/zip: don't read directories containing file data
authorAlexander Yastrebov <yastrebov.alex@gmail.com>
Fri, 11 Nov 2022 23:23:19 +0000 (23:23 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 14 Nov 2022 14:32:55 +0000 (14:32 +0000)
Fixes #54801

Change-Id: I3d03516792975ddb09835b2621c57e12e7cbad35
GitHub-Last-Rev: 4faa7e14dcc48c05d707f1e137d915da24133e14
GitHub-Pull-Request: golang/go#56714
Reviewed-on: https://go-review.googlesource.com/c/go/+/449955
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
src/archive/zip/reader.go
src/archive/zip/reader_test.go

index db118ce854df021ae847fd90a3a014f5384de128..db9ae3cf366277c38d81f6dc0a93b992f993e89b 100644 (file)
@@ -197,6 +197,13 @@ func (f *File) Open() (io.ReadCloser, error) {
        if err != nil {
                return nil, err
        }
+       if strings.HasSuffix(f.Name, "/") {
+               if f.CompressedSize64 != 0 || f.hasDataDescriptor() {
+                       return &dirReader{ErrFormat}, nil
+               } else {
+                       return &dirReader{io.EOF}, nil
+               }
+       }
        size := int64(f.CompressedSize64)
        r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
        dcomp := f.zip.decompressor(f.Method)
@@ -228,6 +235,18 @@ func (f *File) OpenRaw() (io.Reader, error) {
        return r, nil
 }
 
+type dirReader struct {
+       err error
+}
+
+func (r *dirReader) Read([]byte) (int, error) {
+       return 0, r.err
+}
+
+func (r *dirReader) Close() error {
+       return nil
+}
+
 type checksumReader struct {
        rc    io.ReadCloser
        hash  hash.Hash32
index 84742c7d2af3c78b98bb7f936fb249bd39eb6c4b..3123892fb762c2207fdb1a9ebc89c9a60ba41c1f 100644 (file)
@@ -1554,3 +1554,33 @@ func TestUnderSize(t *testing.T) {
                })
        }
 }
+
+func TestIssue54801(t *testing.T) {
+       for _, input := range []string{"testdata/readme.zip", "testdata/dd.zip"} {
+               z, err := OpenReader(input)
+               if err != nil {
+                       t.Fatal(err)
+               }
+               defer z.Close()
+
+               for _, f := range z.File {
+                       // Make file a directory
+                       f.Name += "/"
+
+                       t.Run(f.Name, func(t *testing.T) {
+                               t.Logf("CompressedSize64: %d, Flags: %#x", f.CompressedSize64, f.Flags)
+
+                               rd, err := f.Open()
+                               if err != nil {
+                                       t.Fatal(err)
+                               }
+                               defer rd.Close()
+
+                               n, got := io.Copy(io.Discard, rd)
+                               if n != 0 || got != ErrFormat {
+                                       t.Fatalf("Error mismatch, got: %d, %v, want: %v", n, got, ErrFormat)
+                               }
+                       })
+               }
+       }
+}