1 /*
  2  * Copyright (c) 2019, 2021, 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 import org.testng.annotations.AfterMethod;
 24 import org.testng.annotations.BeforeMethod;
 25 import org.testng.annotations.Test;
 26 
 27 import java.io.*;
 28 import java.nio.file.Files;
 29 import java.nio.file.Path;
 30 import java.util.List;
 31 import java.util.zip.ZipEntry;
 32 import java.util.zip.ZipFile;
 33 import java.util.zip.ZipOutputStream;
 34 
 35 import static org.testng.Assert.assertTrue;
 36 
 37 /**
 38  * @test
 39  * @bug 8226530
 40  * @summary ZIP File System tests that leverage DirectoryStream
 41  * @compile Zip64SizeTest.java
 42  * @run testng Zip64SizeTest
 43  */
 44 public class Zip64SizeTest {
 45 
 46     private static final int BUFFER_SIZE = 2048;
 47     // ZIP file to create
 48     private static final String ZIP_FILE_NAME = "Zip64SizeTest.zip";
 49     // File that will be created with a size greater than 0xFFFFFFFF
 50     private static final String LARGE_FILE_NAME = "LargeZipEntry.txt";
 51     // File that will be created with a size less than 0xFFFFFFFF
 52     private static final String SMALL_FILE_NAME = "SmallZipEntry.txt";
 53     // List of files to be added to the ZIP file
 54     private static final List<String> ZIP_ENTRIES = List.of(LARGE_FILE_NAME,
 55             SMALL_FILE_NAME);
 56     private static final long LARGE_FILE_SIZE = 5L * 1024L * 1024L * 1024L; // 5GB
 57     private static final long SMALL_FILE_SIZE = 0x100000L; // 1024L x 1024L;
 58 
 59     /**
 60      * Validate that if the size of a ZIP entry exceeds 0xFFFFFFFF, that the
 61      * correct size is returned from the ZIP64 Extended information.
 62      * @throws IOException
 63      */
 64     @Test
 65     private static void validateZipEntrySizes() throws IOException {
 66         createFiles();
 67         createZipFile();
 68         System.out.println("Validating Zip Entry Sizes");
 69         try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) {
 70             ZipEntry ze = zip.getEntry(LARGE_FILE_NAME);
 71             System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize());
 72             assertTrue(ze.getSize() == LARGE_FILE_SIZE);
 73             ze = zip.getEntry(SMALL_FILE_NAME);
 74             System.out.printf("Entry: %s, size= %s%n", ze.getName(), ze.getSize());
 75             assertTrue(ze.getSize() == SMALL_FILE_SIZE);
 76 
 77         }
 78     }
 79 
 80     /**
 81      * Delete the files created for use by the test
 82      * @throws IOException if an error occurs deleting the files
 83      */
 84     private static void deleteFiles() throws IOException {
 85         Files.deleteIfExists(Path.of(ZIP_FILE_NAME));
 86         Files.deleteIfExists(Path.of(LARGE_FILE_NAME));
 87         Files.deleteIfExists(Path.of(SMALL_FILE_NAME));
 88     }
 89 
 90     /**
 91      * Create the ZIP file adding an entry whose size exceeds 0xFFFFFFFF
 92      * @throws IOException if an error occurs creating the ZIP File
 93      */
 94     private static void createZipFile() throws IOException {
 95         try (FileOutputStream fos = new FileOutputStream(ZIP_FILE_NAME);
 96              ZipOutputStream zos = new ZipOutputStream(fos)) {
 97             System.out.printf("Creating Zip file: %s%n", ZIP_FILE_NAME);
 98             for (String srcFile : ZIP_ENTRIES) {
 99                 System.out.printf("...Adding Entry: %s%n", srcFile);
100                 File fileToZip = new File(srcFile);
101                 try (FileInputStream fis = new FileInputStream(fileToZip)) {
102                     ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
103                     zipEntry.setSize(fileToZip.length());
104                     zos.putNextEntry(zipEntry);
105                     byte[] bytes = new byte[BUFFER_SIZE];
106                     int length;
107                     while ((length = fis.read(bytes)) >= 0) {
108                         zos.write(bytes, 0, length);
109                     }
110                 }
111             }
112         }
113     }
114 
115     /**
116      * Create the files that will be added to the ZIP file
117      * @throws IOException if there is a problem  creating the files
118      */
119     private static void createFiles() throws IOException {
120         try (RandomAccessFile largeFile = new RandomAccessFile(LARGE_FILE_NAME, "rw");
121              RandomAccessFile smallFile = new RandomAccessFile(SMALL_FILE_NAME, "rw")) {
122             System.out.printf("Creating %s%n", LARGE_FILE_NAME);
123             largeFile.setLength(LARGE_FILE_SIZE);
124             System.out.printf("Creating %s%n", SMALL_FILE_NAME);
125             smallFile.setLength(SMALL_FILE_SIZE);
126         }
127     }
128 
129     /**
130      * Make sure the needed test files do not exist prior to executing the test
131      * @throws IOException
132      */
133     @BeforeMethod
134     public void setUp() throws IOException {
135         deleteFiles();
136     }
137 
138     /**
139      * Remove the files created for the test
140      * @throws IOException
141      */
142     @AfterMethod
143     public void tearDown() throws IOException {
144         deleteFiles();
145     }
146 }