1 |
# HG changeset patch |
2 |
# User kizune |
3 |
# Date 1403186822 -14400 |
4 |
# Thu Jun 19 18:07:02 2014 +0400 |
5 |
# Node ID ad88ac6bac57e540e87fdb5d9ad15528b1beee11 |
6 |
# Parent f0137fa5ba5298a73f14ae508463dc7e890a70a5 |
7 |
8000650, PR2462: unpack200.exe should check gzip crc |
8 |
Reviewed-by: ksrini |
9 |
|
10 |
diff -r f0137fa5ba52 -r ad88ac6bac57 src/share/native/com/sun/java/util/jar/pack/main.cpp |
11 |
--- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp Thu Apr 23 13:48:02 2015 -0400 |
12 |
+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp Thu Jun 19 18:07:02 2014 +0400 |
13 |
@@ -62,6 +62,13 @@ |
14 |
return unpacker::run(argc, argv); |
15 |
} |
16 |
|
17 |
+// Dealing with big-endian arch |
18 |
+#ifdef _BIG_ENDIAN |
19 |
+#define SWAP_INT(a) (((a>>24)&0xff) | ((a<<8)&0xff0000) | ((a>>8)&0xff00) | ((a<<24)&0xff000000)) |
20 |
+#else |
21 |
+#define SWAP_INT(a) (a) |
22 |
+#endif |
23 |
+ |
24 |
// Single-threaded, implementation, not reentrant. |
25 |
// Includes a weak error check against MT access. |
26 |
#ifndef THREAD_SELF |
27 |
@@ -385,6 +392,7 @@ |
28 |
u.start(); |
29 |
} |
30 |
} else { |
31 |
+ u.gzcrc = 0; |
32 |
u.start(peek, sizeof(peek)); |
33 |
} |
34 |
|
35 |
@@ -425,7 +433,23 @@ |
36 |
status = 1; |
37 |
} |
38 |
|
39 |
- if (u.infileptr != null) { |
40 |
+ if (!u.aborting() && u.infileptr != null) { |
41 |
+ if (u.gzcrc != 0) { |
42 |
+ // Read the CRC information from the gzip container |
43 |
+ fseek(u.infileptr, -8, SEEK_END); |
44 |
+ uint filecrc; |
45 |
+ fread(&filecrc, sizeof(filecrc), 1, u.infileptr); |
46 |
+ if (u.gzcrc != SWAP_INT(filecrc)) { // CRC error |
47 |
+ if (strcmp(destination_file, "-") != 0) { |
48 |
+ // Output is not stdout, remove it, it's broken |
49 |
+ if (u.jarout != null) |
50 |
+ u.jarout->closeJarFile(false); |
51 |
+ remove(destination_file); |
52 |
+ } |
53 |
+ // Print out the error and exit with return code != 0 |
54 |
+ u.abort("CRC error, invalid compressed data."); |
55 |
+ } |
56 |
+ } |
57 |
fclose(u.infileptr); |
58 |
u.infileptr = null; |
59 |
} |
60 |
diff -r f0137fa5ba52 -r ad88ac6bac57 src/share/native/com/sun/java/util/jar/pack/unpack.h |
61 |
--- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h Thu Apr 23 13:48:02 2015 -0400 |
62 |
+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h Thu Jun 19 18:07:02 2014 +0400 |
63 |
@@ -171,6 +171,7 @@ |
64 |
bytes inbytes; // direct |
65 |
gunzip* gzin; // gunzip filter, if any |
66 |
jar* jarout; // output JAR file |
67 |
+ uint gzcrc; // CRC gathered from gzip content |
68 |
|
69 |
#ifndef PRODUCT |
70 |
int nowrite; |
71 |
diff -r f0137fa5ba52 -r ad88ac6bac57 src/share/native/com/sun/java/util/jar/pack/zip.cpp |
72 |
--- openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Thu Apr 23 13:48:02 2015 -0400 |
73 |
+++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Thu Jun 19 18:07:02 2014 +0400 |
74 |
@@ -551,6 +551,7 @@ |
75 |
break; |
76 |
} |
77 |
int nr = readlen - zs.avail_out; |
78 |
+ u->gzcrc = crc32(u->gzcrc, (const unsigned char *)bufptr, nr); |
79 |
numread += nr; |
80 |
bufptr += nr; |
81 |
assert(numread <= maxlen); |
82 |
@@ -589,6 +590,7 @@ |
83 |
zstream = NEW(z_stream, 1); |
84 |
u->gzin = this; |
85 |
u->read_input_fn = read_input_via_gzip; |
86 |
+ u->gzcrc = crc32(0L, Z_NULL, 0); |
87 |
} |
88 |
|
89 |
void gunzip::start(int magic) { |
90 |
diff -r f0137fa5ba52 -r ad88ac6bac57 test/tools/pack200/PackChecksum.java |
91 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
92 |
+++ openjdk/jdk/test/tools/pack200/PackChecksum.java Thu Jun 19 18:07:02 2014 +0400 |
93 |
@@ -0,0 +1,107 @@ |
94 |
+/* |
95 |
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
96 |
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
97 |
+ * |
98 |
+ * This code is free software; you can redistribute it and/or modify it |
99 |
+ * under the terms of the GNU General Public License version 2 only, as |
100 |
+ * published by the Free Software Foundation. |
101 |
+ * |
102 |
+ * This code is distributed in the hope that it will be useful, but WITHOUT |
103 |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
104 |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
105 |
+ * version 2 for more details (a copy is included in the LICENSE file that |
106 |
+ * accompanied this code). |
107 |
+ * |
108 |
+ * You should have received a copy of the GNU General Public License version |
109 |
+ * 2 along with this work; if not, write to the Free Software Foundation, |
110 |
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
111 |
+ * |
112 |
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
113 |
+ * or visit www.oracle.com if you need additional information or have any |
114 |
+ * questions. |
115 |
+ */ |
116 |
+import java.io.File; |
117 |
+import java.io.FileOutputStream; |
118 |
+import java.io.IOException; |
119 |
+import java.io.RandomAccessFile; |
120 |
+import java.util.ArrayList; |
121 |
+import java.util.List; |
122 |
+import java.util.jar.JarEntry; |
123 |
+import java.util.jar.JarOutputStream; |
124 |
+ |
125 |
+/* |
126 |
+ * @test |
127 |
+ * @bug 8000650 |
128 |
+ * @summary unpack200.exe should check gzip crc |
129 |
+ * @compile -XDignore.symbol.file Utils.java PackChecksum.java |
130 |
+ * @run main PackChecksum |
131 |
+ * @author kizune |
132 |
+ */ |
133 |
+public class PackChecksum { |
134 |
+ |
135 |
+ public static void main(String... args) throws Exception { |
136 |
+ testChecksum(); |
137 |
+ } |
138 |
+ |
139 |
+ static void testChecksum() throws Exception { |
140 |
+ |
141 |
+ // Create a fresh .jar file |
142 |
+ File testFile = new File("src_tools.jar"); |
143 |
+ File testPack = new File("src_tools.pack.gz"); |
144 |
+ generateJar(testFile); |
145 |
+ List<String> cmdsList = new ArrayList<>(); |
146 |
+ |
147 |
+ // Create .pack file |
148 |
+ cmdsList.add(Utils.getPack200Cmd()); |
149 |
+ cmdsList.add(testPack.getName()); |
150 |
+ cmdsList.add(testFile.getName()); |
151 |
+ Utils.runExec(cmdsList); |
152 |
+ |
153 |
+ // Mess up with the checksum of the packed file |
154 |
+ RandomAccessFile raf = new RandomAccessFile(testPack, "rw"); |
155 |
+ raf.seek(raf.length() - 8); |
156 |
+ int val = raf.readInt(); |
157 |
+ val = Integer.MAX_VALUE - val; |
158 |
+ raf.seek(raf.length() - 8); |
159 |
+ raf.writeInt(val); |
160 |
+ raf.close(); |
161 |
+ |
162 |
+ File dstFile = new File("dst_tools.jar"); |
163 |
+ cmdsList.clear(); |
164 |
+ cmdsList.add(Utils.getUnpack200Cmd()); |
165 |
+ cmdsList.add(testPack.getName()); |
166 |
+ cmdsList.add(dstFile.getName()); |
167 |
+ |
168 |
+ boolean passed = false; |
169 |
+ try { |
170 |
+ Utils.runExec(cmdsList); |
171 |
+ } catch (RuntimeException re) { |
172 |
+ // unpack200 should exit with non-zero exit code |
173 |
+ passed = true; |
174 |
+ } |
175 |
+ |
176 |
+ // tidy up |
177 |
+ if (testFile.exists()) testFile.delete(); |
178 |
+ if (testPack.exists()) testPack.delete(); |
179 |
+ if (dstFile.exists()) dstFile.delete(); |
180 |
+ if (!passed) { |
181 |
+ throw new Exception("File with incorrect CRC unpacked without the error."); |
182 |
+ } |
183 |
+ } |
184 |
+ |
185 |
+ static void generateJar(File result) throws IOException { |
186 |
+ if (result.exists()) { |
187 |
+ result.delete(); |
188 |
+ } |
189 |
+ |
190 |
+ try (JarOutputStream output = new JarOutputStream(new FileOutputStream(result)); ) { |
191 |
+ for (int i = 0 ; i < 100 ; i++) { |
192 |
+ JarEntry e = new JarEntry("F-" + i + ".txt"); |
193 |
+ output.putNextEntry(e); |
194 |
+ } |
195 |
+ output.flush(); |
196 |
+ output.close(); |
197 |
+ } |
198 |
+ } |
199 |
+ |
200 |
+} |