1 /*
2  * Copyright (c) 2003, 2011, 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 4334846
26    @summary Make sure zip file comments of various sizes can be written.
27    @author Martin Buchholz
28  */
29 
30 import java.io.*;
31 
32 import java.util.zip.ZipEntry;
33 import java.util.zip.ZipFile;
34 import java.util.zip.ZipOutputStream;
35 
36 public class Comment {
37     private static final String entryName = "entryName";
38     private static final String entryContents = "entryContents";
39     private static final int commentMaxLength = 0xFFFF;
40     private static final int [] commentLengths
41         = { 0, 1, 32768, commentMaxLength - 1, commentMaxLength };
42 
main(String argv[])43     public static void main(String argv[])
44         throws Exception
45     {
46         for (int i = 0; i < commentLengths.length; ++i) {
47             int commentLength = commentLengths[i];
48             String comment = buildComment(commentLength);
49             String name = "Test" + commentLength + ".zip";
50             writeZipFile(name, comment);
51             verifyZipFile(name, comment);
52             new File(name).delete();
53             System.out.println(commentLength + ": successful");
54         }
55     }
56 
writeZipFile(String name, String comment)57     private static void writeZipFile(String name, String comment)
58         throws IOException
59     {
60         try (FileOutputStream fos = new FileOutputStream(name);
61              ZipOutputStream zos = new ZipOutputStream(fos))
62         {
63             zos.setComment(comment);
64             ZipEntry ze = new ZipEntry(entryName);
65             ze.setMethod(ZipEntry.DEFLATED);
66             zos.putNextEntry(ze);
67             new DataOutputStream(zos).writeUTF(entryContents);
68             zos.closeEntry();
69         }
70     }
71 
verifyZipFile(String name, String comment)72     private static void verifyZipFile(String name, String comment)
73         throws Exception
74     {
75         // Check that Zip entry was correctly written.
76         try (ZipFile zipFile = new ZipFile(name)) {
77             ZipEntry zipEntry = zipFile.getEntry(entryName);
78             InputStream is = zipFile.getInputStream(zipEntry);
79             String result = new DataInputStream(is).readUTF();
80             if (!result.equals(entryContents))
81                 throw new Exception("Entry contents corrupted");
82         }
83 
84         try (RandomAccessFile file = new RandomAccessFile(name, "r")) {
85             // Check that comment length was correctly written.
86             file.seek(file.length() - comment.length()
87                       - ZipFile.ENDHDR + ZipFile.ENDCOM);
88             int b1 = file.readUnsignedByte();
89             int b2 = file.readUnsignedByte();
90             if (b1 + (b2 << 8) != comment.length())
91                 throw new Exception("Zip file comment length corrupted");
92 
93             // Check that comment was correctly written.
94             file.seek(file.length() - comment.length());
95             byte [] bytes = new byte [comment.length()];
96             file.readFully(bytes);
97             if (! comment.equals(new String(bytes, "UTF8")))
98                 throw new Exception("Zip file comment corrupted");
99         }
100     }
101 
buildComment(int length)102     private static String buildComment(int length) {
103         StringBuffer result = new StringBuffer();
104         while (result.length() < length) {
105             /* Endhdr is 22 bytes long, so this pattern makes it easy
106              * to see if it is copied correctly */
107             result.append("abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUV");
108         }
109         String string = result.toString();
110         string = string.substring(string.length() - length);
111         return string;
112     }
113 }
114