]> Cypherpunks repositories - gostls13.git/commitdiff
archive/zip: handle zip files with more than 65535 files
authorAndrew Gerrand <adg@golang.org>
Fri, 22 Jul 2011 04:57:17 +0000 (14:57 +1000)
committerAndrew Gerrand <adg@golang.org>
Fri, 22 Jul 2011 04:57:17 +0000 (14:57 +1000)
R=r
CC=golang-dev
https://golang.org/cl/4812048

src/pkg/archive/zip/reader.go

index 7deff117cb35c09487a5b3d1d325eaff4c94de2a..98d4fb9943968463ae93998efc5ee3771d269a19 100644 (file)
@@ -80,19 +80,33 @@ func (z *Reader) init(r io.ReaderAt, size int64) os.Error {
                return err
        }
        z.r = r
-       z.File = make([]*File, end.directoryRecords)
+       z.File = make([]*File, 0, end.directoryRecords)
        z.Comment = end.comment
        rs := io.NewSectionReader(r, 0, size)
        if _, err = rs.Seek(int64(end.directoryOffset), os.SEEK_SET); err != nil {
                return err
        }
        buf := bufio.NewReader(rs)
-       for i := range z.File {
-               z.File[i] = &File{zipr: r, zipsize: size}
-               if err := readDirectoryHeader(z.File[i], buf); err != nil {
+
+       // The count of files inside a zip is truncated to fit in a uint16.
+       // Gloss over this by reading headers until we encounter
+       // a bad one, and then only report a FormatError if
+       // the file count modulo 65536 is incorrect.
+       for {
+               f := &File{zipr: r, zipsize: size}
+               err := readDirectoryHeader(f, buf)
+               if err == FormatError {
+                       break
+               }
+               if err != nil {
                        return err
                }
+               z.File = append(z.File, f)
        }
+       if uint16(len(z.File)) != end.directoryRecords {
+               return FormatError
+       }
+
        return nil
 }