1 /*
   2  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @bug 4770745 4828461
  26  * @summary open zip files with more than 64k entries
  27  * @run main/timeout=600 ManyEntries
  28  * @author Martin Buchholz
  29  */
  30 
  31 import java.util.*;
  32 import java.util.zip.*;
  33 import java.io.*;
  34 
  35 public class ManyEntries {
  36     public static void main(String[] args) throws Exception {
  37         boolean runMoreTests = args.length > 0;
  38         int[] sizes = (runMoreTests ?
  39                        new int[]{1, 2, 42, 65534, 65535, 65536, 65537, 68000} :
  40                        new int[]{1, 2, 42, 68000});
  41         int[] methods = {ZipEntry.STORED, ZipEntry.DEFLATED};
  42 
  43         for (int size : sizes)
  44             for (int method : methods)
  45                 test(size, method);
  46     }
  47 
  48     // JDK doesn't like having zip file contents changed at runtime
  49     static int uniquifier = 42;
  50 
  51     static void test(int N, int method) throws Exception {
  52         System.out.println("N="+N+", method="+method);
  53         long time = System.currentTimeMillis() / 2000 * 2000;
  54         CRC32 crc32 = new CRC32();
  55         File zipFile = new File(++uniquifier + ".zip");
  56         try {
  57             zipFile.delete();
  58             ZipOutputStream zos = new ZipOutputStream(
  59                 new BufferedOutputStream(
  60                     new FileOutputStream(zipFile)));
  61             try {
  62                 for (int i = 0; i < N; i++) {
  63                     ZipEntry e = new ZipEntry("DIR/"+i);
  64                     e.setMethod(method);
  65                     e.setTime(time);
  66                     if (method == ZipEntry.STORED) {
  67                         e.setSize(1);
  68                         crc32.reset();
  69                         crc32.update((byte)i);
  70                         e.setCrc(crc32.getValue());
  71                     } else {
  72                         e.setSize(0);
  73                         e.setCrc(0);
  74                     }
  75                     zos.putNextEntry(e);
  76                     zos.write(i);
  77                 }
  78             } finally {
  79                 zos.close();
  80                 zos = null;
  81             }
  82 
  83             ZipFile zip = zip = new ZipFile(zipFile);
  84             try {
  85                 if (! (zip.size() == N))
  86                     throw new Exception("Bad ZipFile size: " + zip.size());
  87                 Enumeration entries = zip.entries();
  88 
  89                 for (int i = 0; i < N; i++) {
  90                     if (i % 1000 == 0) {System.gc(); System.runFinalization();}
  91                     if (! (entries.hasMoreElements()))
  92                         throw new Exception("only " + i + " elements");
  93                     ZipEntry e = (ZipEntry)entries.nextElement();
  94                     if (! (e.getSize() == 1))
  95                         throw new Exception("bad size: " + e.getSize());
  96                     if (! (e.getName().equals("DIR/" + i)))
  97                         throw new Exception("bad name: " + i);
  98                     if (! (e.getMethod() == method))
  99                         throw new Exception("getMethod="+e.getMethod()+", method=" + method);
 100                     if (! (e.getTime() == time))
 101                         throw new Exception("getTime="+e.getTime()+", time=" + time);
 102                     if (! (zip.getInputStream(e).read() == (i & 0xff)))
 103                         throw new Exception("Bad file contents: " + i);
 104                 }
 105                 if (entries.hasMoreElements())
 106                     throw new Exception("too many elements");
 107             } finally {
 108                 zip.close();
 109             }
 110         }
 111         finally {
 112             zipFile.delete();
 113         }
 114     }
 115 }