1 /*
   2  * Copyright (c) 2014, 2016, 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 java.io.File;
  24 import java.io.FileOutputStream;
  25 import java.io.IOException;
  26 import java.io.RandomAccessFile;
  27 import java.util.ArrayList;
  28 import java.util.List;
  29 import java.util.jar.JarEntry;
  30 import java.util.jar.JarOutputStream;
  31 
  32 /*
  33  * @test
  34  * @bug 8000650 8150469
  35  * @summary unpack200.exe should check gzip crc
  36  * @compile -XDignore.symbol.file Utils.java PackChecksum.java
  37  * @run main PackChecksum
  38  * @author kizune
  39  */
  40 public class PackChecksum {
  41     final int TRAILER_LEN = 8;
  42     final List<String> cmdsList = new ArrayList<>();
  43     static enum Case {
  44         CRC32,
  45         ISIZE,
  46         BOTH;
  47 
  48     };
  49     public static void main(String... args) throws Exception {
  50         new PackChecksum().run();
  51     }
  52     void run() throws Exception {
  53         testChecksum(Case.CRC32); // negative
  54         testChecksum(Case.ISIZE); // negative
  55         testChecksum(Case.BOTH);  // negative
  56         testMultipleSegments();
  57     }
  58 
  59     void testMultipleSegments() throws Exception {
  60         File inputJar = new File("input.jar");
  61         Utils.copyFile(Utils.getGoldenJar(), inputJar);
  62         cmdsList.clear();
  63 
  64         File testPack = new File("out.jar.pack.gz");
  65 
  66         cmdsList.clear();
  67         cmdsList.add(Utils.getPack200Cmd());
  68         // force multiple segments
  69         cmdsList.add("--segment-limit=100");
  70         cmdsList.add(testPack.getName());
  71         cmdsList.add(inputJar.getName());
  72         Utils.runExec(cmdsList);
  73 
  74         File destFile = new File("dst.jar");
  75         cmdsList.clear();
  76         cmdsList.add(Utils.getUnpack200Cmd());
  77         cmdsList.add(testPack.getName());
  78         cmdsList.add(destFile.getName());
  79         try {
  80             Utils.runExec(cmdsList);
  81             if (!destFile.exists()) {
  82                 throw new Exception("file not created: " + destFile);
  83             }
  84         } finally {
  85             if (inputJar.exists())
  86                 inputJar.delete();
  87             if (testPack.exists())
  88                 testPack.delete();
  89             if (destFile.exists())
  90                 destFile.delete();
  91         }
  92     }
  93 
  94     void testChecksum(Case type) throws Exception {
  95         System.out.println("Testing: case " + type);
  96         // Create a fresh .jar file
  97         File testFile = new File("src_tools.jar");
  98         File testPack = new File("src_tools.pack.gz");
  99         generateJar(testFile);
 100 
 101         cmdsList.clear();
 102         // Create .pack file
 103         cmdsList.add(Utils.getPack200Cmd());
 104         cmdsList.add(testPack.getName());
 105         cmdsList.add(testFile.getName());
 106         Utils.runExec(cmdsList);
 107 
 108         // mutate the checksum of the packed file
 109         RandomAccessFile raf = new RandomAccessFile(testPack, "rw");
 110 
 111         switch (type) {
 112             case CRC32:
 113                 raf.seek(raf.length() - TRAILER_LEN);
 114                 raf.writeInt(0x0dea0a0d);
 115                 break;
 116             case ISIZE:
 117                 raf.seek(raf.length() - (TRAILER_LEN/2));
 118                 raf.writeInt(0x0b0e0e0f);
 119                 break;
 120             default:
 121                 raf.seek(raf.length() - (TRAILER_LEN));
 122                 raf.writeLong(0x0dea0a0d0b0e0e0fL);
 123                 break;
 124         }
 125 
 126         raf.close();
 127 
 128         File dstFile = new File("dst_tools.jar");
 129         if (dstFile.exists()) {
 130             dstFile.delete();
 131         }
 132         cmdsList.clear();
 133         cmdsList.add(Utils.getUnpack200Cmd());
 134         cmdsList.add(testPack.getName());
 135         cmdsList.add(dstFile.getName());
 136 
 137         boolean processFailed = false;
 138         try {
 139             Utils.runExec(cmdsList);
 140         } catch (RuntimeException re) {
 141             // unpack200 should exit with non-zero exit code
 142             processFailed = true;
 143         } finally {
 144             // tidy up
 145             if (testFile.exists())
 146                 testFile.delete();
 147 
 148             if (testPack.exists())
 149                 testPack.delete();
 150 
 151             if (!processFailed) {
 152                 throw new Exception("case " + type +
 153                         ": file with incorrect CRC, unpacked without the error.");
 154             }
 155             if (dstFile.exists()) {
 156                 dstFile.delete();
 157                 throw new Exception("case " + type +
 158                         ":  file exists: " + dstFile);
 159             }
 160         }
 161     }
 162 
 163     void generateJar(File result) throws IOException {
 164         if (result.exists()) {
 165             result.delete();
 166         }
 167 
 168         try (JarOutputStream output = new JarOutputStream(new FileOutputStream(result)); ) {
 169             for (int i = 0 ; i < 100 ; i++) {
 170                 JarEntry e = new JarEntry("F-" + i + ".txt");
 171                 output.putNextEntry(e);
 172             }
 173             output.flush();
 174             output.close();
 175         }
 176     }
 177 
 178 }