--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/6842838/CreateBadJar.java Mon Sep 14 20:55:08 2009 +0100
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Borrowing significantly from Martin Buchholz's CorruptedZipFiles.java
+ *
+ * Needed a way of testing the checks for corrupt zip/jar entry in
+ * inflate_file from file j2se/src/share/bin/parse_manifest.c
+ * and running them with the 64-bit launcher. e.g.
+ * sparcv9/bin/java -jar badjar.jar
+ *
+ * Run from a script driver Test6842838.sh as we want to specifically run
+ * bin/sparcv9/java, the 64-bit launcher.
+ *
+ * So this program will create a zip file and damage it in the way
+ * required to tickle this bug.
+ *
+ * It will cause a buffer overrun: but that will not always crash.
+ * Use libumem preloaded by the script driver in order to
+ * abort quickly when the overrun happens. That makes the test
+ * Solaris-specific.
+ */
+
+import java.util.*;
+import java.util.zip.*;
+import java.io.*;
+import static java.lang.System.*;
+import static java.util.zip.ZipFile.*;
+
+public class CreateBadJar {
+
+public static void main(String [] arguments) {
+
+ if (arguments.length != 2) {
+ throw new RuntimeException("Arguments: jarfilename entryname");
+ }
+ String outFile = arguments[0];
+ String entryName = arguments[1];
+
+ try {
+ // If the named file doesn't exist, create it.
+ // If it does, we are expecting it to contain the named entry, for
+ // alteration.
+ if (!new File(outFile).exists()) {
+ System.out.println("Creating file " + outFile);
+
+ // Create the requested zip/jar file.
+ ZipOutputStream zos = null;
+ zos = new ZipOutputStream(
+ new FileOutputStream(outFile));
+
+ ZipEntry e = new ZipEntry(entryName);
+ zos.putNextEntry(e);
+ for (int j=0; j<50000; j++) {
+ zos.write((int)'a');
+ }
+ zos.closeEntry();
+ zos.close();
+ zos = null;
+ }
+
+ // Read it.
+ int len = (int)(new File(outFile).length());
+ byte[] good = new byte[len];
+ FileInputStream fis = new FileInputStream(outFile);
+ fis.read(good);
+ fis.close();
+ fis = null;
+
+ int endpos = len - ENDHDR;
+ int cenpos = u16(good, endpos+ENDOFF);
+ if (u32(good, cenpos) != CENSIG) throw new RuntimeException("Where's CENSIG?");
+
+ byte[] bad;
+ bad = good.clone();
+
+ // Corrupt it...
+ int pos = findInCEN(bad, cenpos, entryName);
+
+ // What bad stuff are we doing to it?
+ // Store a 32-bit -1 in uncomp size.
+ bad[pos+0x18]=(byte)0xff;
+ bad[pos+0x19]=(byte)0xff;
+ bad[pos+0x1a]=(byte)0xff;
+ bad[pos+0x1b]=(byte)0xff;
+
+ // Bad work complete, delete the original.
+ new File(outFile).delete();
+
+ // Write it.
+ FileOutputStream fos = new FileOutputStream(outFile);
+ fos.write(bad);
+ fos.close();
+ fos = null;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+}
+
+ /*
+ * Scan Central Directory File Headers looking for the named entry.
+ */
+
+ static int findInCEN(byte[] bytes, int cenpos, String entryName) {
+ int pos = cenpos;
+ int nextPos = 0;
+ String filename = null;
+ do {
+ if (nextPos != 0) {
+ pos = nextPos;
+ }
+ System.out.println("entry at pos = " + pos);
+ if (u32(bytes, pos) != CENSIG) throw new RuntimeException ("entry not found in CEN or premature end...");
+
+ int csize = u32(bytes, pos+0x14); // +0x14 1 dword csize
+ int uncompsize = u32(bytes, pos+0x18); // +0x18 1 dword uncomp size
+ int filenameLength = u16(bytes, pos+0x1c); // +0x1c 1 word length of filename
+ int extraLength = u16(bytes, pos+0x1e); // +0x1e 1 world length of extra field
+ int commentLength = u16(bytes, pos+0x20); // +0x20 1 world length of file comment
+ filename = new String(bytes, pos+0x2e, filenameLength); // +0x2e chars of filename
+ int offset = u32(bytes, pos+0x2a); // +0x2a chars of filename
+
+ System.out.println("filename = " + filename + "\ncsize = " + csize +
+ " uncomp.size = " + uncompsize +" file offset = " + offset);
+ nextPos = pos + 0x2e + filenameLength + extraLength + commentLength;
+
+ } while (!filename.equals(entryName));
+
+ System.out.println("entry found at pos = " + pos);
+ return pos;
+ }
+
+ static int u8(byte[] data, int offset) {
+ return data[offset]&0xff;
+ }
+
+ static int u16(byte[] data, int offset) {
+ return u8(data,offset) + (u8(data,offset+1)<<8);
+ }
+
+ static int u32(byte[] data, int offset) {
+ return u16(data,offset) + (u16(data,offset+2)<<16);
+ }
+
+}
+