]> Cypherpunks repositories - gostls13.git/commitdiff
archive/zip: fixes unexpected EOF when reading archive
authoralexander demakin <alexander.demakin@gmail.com>
Thu, 10 Sep 2015 16:43:20 +0000 (19:43 +0300)
committerAndrew Gerrand <adg@golang.org>
Fri, 11 Sep 2015 00:32:59 +0000 (00:32 +0000)
If comment of the archive contains data which looks like
a zip64 directory, the comment is parsed as an
actual directory header.
Commit adds some additional checks similar to the checks
in minizip library.

Fixes #12449

Change-Id: Ia0fc950e47b9c39f77d88401b9ca30100ca7c808
Reviewed-on: https://go-review.googlesource.com/14433
Run-TryBot: Andrew Gerrand <adg@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
src/archive/zip/reader.go
src/archive/zip/reader_test.go

index 519748bac4006325228819074c7c984b9865063b..0f7086081a9cec992fea6ae79748c2040ba64660 100644 (file)
@@ -376,14 +376,16 @@ func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error)
        }
        d.comment = string(b[:l])
 
-       p, err := findDirectory64End(r, directoryEndOffset)
-       if err == nil && p >= 0 {
-               err = readDirectory64End(r, p, d)
-       }
-       if err != nil {
-               return nil, err
+       // These values mean that the file can be a zip64 file
+       if d.directoryRecords == 0xffff || d.directorySize == 0xffff || d.directoryOffset == 0xffffffff {
+               p, err := findDirectory64End(r, directoryEndOffset)
+               if err == nil && p >= 0 {
+                       err = readDirectory64End(r, p, d)
+               }
+               if err != nil {
+                       return nil, err
+               }
        }
-
        // Make sure directoryOffset points to somewhere in our file.
        if o := int64(d.directoryOffset); o < 0 || o >= size {
                return nil, ErrFormat
@@ -407,8 +409,13 @@ func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error)
        if sig := b.uint32(); sig != directory64LocSignature {
                return -1, nil
        }
-       b = b[4:]       // skip number of the disk with the start of the zip64 end of central directory
-       p := b.uint64() // relative offset of the zip64 end of central directory record
+       if b.uint32() != 0 { // number of the disk with the start of the zip64 end of central directory
+               return -1, nil // the file is not a valid zip64-file
+       }
+       p := b.uint64()      // relative offset of the zip64 end of central directory record
+       if b.uint32() != 1 { // total number of disks
+               return -1, nil // the file is not a valid zip64-file
+       }
        return int64(p), nil
 }
 
index 547dd39048e21749faa6bebb159734bc4caf1599..8f7e8bf555d31cdb12f62cbc4aa2fb9f48d88ccc 100644 (file)
@@ -605,3 +605,40 @@ func TestIssue11146(t *testing.T) {
        }
        r.Close()
 }
+
+// Verify we do not treat non-zip64 archives as zip64
+func TestIssue12449(t *testing.T) {
+       data := []byte{
+               0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
+               0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46, 0x00, 0x00,
+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0xca, 0x64,
+               0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
+               0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+               0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
+               0x00, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x0a,
+               0x50, 0x4b, 0x07, 0x08, 0x1d, 0x88, 0x77, 0xb0,
+               0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+               0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00,
+               0x08, 0x00, 0x00, 0x00, 0x6b, 0xb4, 0xba, 0x46,
+               0x1d, 0x88, 0x77, 0xb0, 0x07, 0x00, 0x00, 0x00,
+               0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00,
+               0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+               0xa0, 0x81, 0x00, 0x00, 0x00, 0x00, 0xca, 0x64,
+               0x55, 0x75, 0x78, 0x0b, 0x00, 0x50, 0x4b, 0x05,
+               0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+               0x00, 0x49, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
+               0x00, 0x97, 0x2b, 0x49, 0x23, 0x05, 0xc5, 0x0b,
+               0xa7, 0xd1, 0x52, 0xa2, 0x9c, 0x50, 0x4b, 0x06,
+               0x07, 0xc8, 0x19, 0xc1, 0xaf, 0x94, 0x9c, 0x61,
+               0x44, 0xbe, 0x94, 0x19, 0x42, 0x58, 0x12, 0xc6,
+               0x5b, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
+               0x00, 0x01, 0x00, 0x01, 0x00, 0x69, 0x00, 0x00,
+               0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
+       }
+       // Read in the archive.
+       _, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
+       if err != nil {
+               t.Errorf("Error reading the archive: %v", err)
+       }
+}