Skip to content

Commit e3243ee

Browse files
committedNov 23, 2021
8277087: ZipException: zip END header not found at ZipFile#Source.findEND
Reviewed-by: lancea
1 parent 12f08ba commit e3243ee

File tree

2 files changed

+117
-3
lines changed

2 files changed

+117
-3
lines changed
 

‎src/java.base/share/classes/java/util/zip/ZipOutputStream.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,14 @@ public ZipOutputStream(OutputStream out, Charset charset) {
144144
* ZIP file comment is greater than 0xFFFF bytes
145145
*/
146146
public void setComment(String comment) {
147+
byte[] bytes = null;
147148
if (comment != null) {
148-
this.comment = zc.getBytes(comment);
149-
if (this.comment.length > 0xffff)
150-
throw new IllegalArgumentException("ZIP file comment too long.");
149+
bytes = zc.getBytes(comment);
150+
if (bytes.length > 0xffff) {
151+
throw new IllegalArgumentException("ZIP file comment too long");
152+
}
151153
}
154+
this.comment = bytes;
152155
}
153156

154157
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright Amazon.com Inc. 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+
import java.io.ByteArrayOutputStream;
25+
import java.util.function.Consumer;
26+
import java.util.zip.ZipEntry;
27+
import java.util.zip.ZipFile;
28+
import java.util.zip.ZipOutputStream;
29+
30+
import org.testng.annotations.DataProvider;
31+
import org.testng.annotations.Test;
32+
33+
import static org.testng.Assert.assertThrows;
34+
35+
/**
36+
* @test
37+
* @bug 8277087
38+
* @summary Verifies various use cases when the zip comment should be empty
39+
* @run testng EmptyComment
40+
*/
41+
public final class EmptyComment {
42+
43+
@DataProvider()
44+
Object[][] longLengths() {
45+
return new Object[][]{{0xFFFF + 1}, {0xFFFF + 2}, {0xFFFF * 2}};
46+
}
47+
48+
/**
49+
* Overflow, the text is too long to be stored as a comment.
50+
*/
51+
@Test(dataProvider = "longLengths")
52+
void testOverflow(int length) throws Exception {
53+
test(zos -> assertThrows(IllegalArgumentException.class, () -> {
54+
zos.setComment("X".repeat(length));
55+
}));
56+
}
57+
58+
/**
59+
* Simple cases where the comment is set to the empty text.
60+
*/
61+
@Test
62+
void testSimpleCases() throws Exception {
63+
test(zos -> {/* do nothing */});
64+
test(zos -> zos.setComment(null));
65+
test(zos -> zos.setComment(""));
66+
test(zos -> {
67+
zos.setComment("");
68+
zos.setComment(null);
69+
});
70+
test(zos -> {
71+
zos.setComment(null);
72+
zos.setComment("");
73+
});
74+
test(zos -> {
75+
zos.setComment("Comment");
76+
zos.setComment(null);
77+
});
78+
test(zos -> {
79+
zos.setComment("Comment");
80+
zos.setComment("");
81+
});
82+
}
83+
84+
private static void test(Consumer<ZipOutputStream> test) throws Exception {
85+
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
86+
ZipOutputStream zos = new ZipOutputStream(baos)) {
87+
88+
test.accept(zos);
89+
90+
zos.putNextEntry(new ZipEntry("x"));
91+
zos.finish();
92+
93+
byte[] data = baos.toByteArray();
94+
95+
if (data.length > 0xFFFF) { // just in case
96+
throw new RuntimeException("data is too big: " + data.length);
97+
}
98+
int pk = data.length - ZipFile.ENDHDR;
99+
if (data[pk] != 'P' || data[pk + 1] != 'K') {
100+
throw new RuntimeException("PK is not found");
101+
}
102+
// Since the comment is empty this will be two last bytes
103+
int pos = data.length - ZipFile.ENDHDR + ZipFile.ENDCOM;
104+
105+
int len = (data[pos] & 0xFF) + ((data[pos + 1] & 0xFF) << 8);
106+
if (len != 0) {
107+
throw new RuntimeException("zip comment is not empty: " + len);
108+
}
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)
Please sign in to comment.