diff options
Diffstat (limited to 'netx/net/sourceforge/jnlp/util/JarFile.java')
-rw-r--r-- | netx/net/sourceforge/jnlp/util/JarFile.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/netx/net/sourceforge/jnlp/util/JarFile.java b/netx/net/sourceforge/jnlp/util/JarFile.java new file mode 100644 index 0000000..8eee518 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/JarFile.java @@ -0,0 +1,153 @@ +/* + Copyright (C) 2012 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + IcedTea 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 for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ +package net.sourceforge.jnlp.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipFile; +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +public class JarFile extends java.util.jar.JarFile { + + public JarFile(String name) throws IOException { + super(name); + verifyZipHeader(new File(name)); + } + + /** + */ + public JarFile(String name, boolean verify) throws IOException { + super(name, verify); + verifyZipHeader(new File(name)); + } + + /** + */ + public JarFile(File file) throws IOException { + super(file); + verifyZipHeader(file); + } + + /** + */ + public JarFile(File file, boolean verify) throws IOException { + super(file, verify); + verifyZipHeader(file); + } + + /* + */ + public JarFile(File file, boolean verify, int mode) throws IOException { + super(file, verify, mode); + verifyZipHeader(file); + } + + + + + /** + * According to specification - + * http://www.pkware.com/documents/casestudies/APPNOTE.TXT or just google + * around zip header all entries in zip-compressed must start with well + * known "PK" which is defined as hexa x50 x4b x03 x04, which in decimal are + * 80 75 3 4. + * + * Note - this is not file-header, it is item-header. + * + * Actually most of compressing formats have some n-bytes header se eg: + * http://www.gzip.org/zlib/rfc-gzip.html#header-trailer for ID1 and ID2 so + * in case that some differently compressed jars will come to play, this is + * the palce where to fix it. + * + */ + private static final byte[] ZIP_LOCAL_FILE_HEADER_SIGNATURE = new byte[]{80, 75, 3, 4}; + + /** + * This method is checking first four bytes of jar-file against + * ZIP_LOCAL_FILE_HEADER_SIGNATURE + * + * Although zip specification allows to skip all corrupted entries, it is + * not safe for jars. If first four bytes of file are not zip + * ZIP_LOCAL_FILE_HEADER_SIGNATURE then exception is thrown + * + * As noted, ZIP_LOCAL_FILE_HEADER_SIGNATURE is not ile-header, but is item-header. + * Possible attack is using the fact that entries without header are considered + * corrupted and so can be ignoered. However, for other they can have some meaning. + * + * So for our purposes we must insists on first record to be valid. + * + * @param file + * @throws IOException, InvalidJarHeaderException + */ + public static void verifyZipHeader(File file) throws IOException { + if (!JNLPRuntime.isIgnoreHeaders()) { + InputStream s = new FileInputStream(file); + try { + byte[] buffer = new byte[ZIP_LOCAL_FILE_HEADER_SIGNATURE.length]; + /* + * for case that new byte[] will accidently initialize same + * sequence as zip header and during the read the buffer will not be filled + */ + for (int i = 0; i < buffer.length; i++) { + buffer[i] = 0; + } + int toRead = ZIP_LOCAL_FILE_HEADER_SIGNATURE.length; + int readSoFar = 0; + int n = 0; + /* + * this is used instead of s.read(buffer) for case of block and + * so returned not-fully-filled dbuffer + */ + while ((n = s.read(buffer, readSoFar, buffer.length - readSoFar)) != -1) { + readSoFar += n; + if (readSoFar == toRead) { + break; + } + } + for (int i = 0; i < buffer.length; i++) { + if (buffer[i] != ZIP_LOCAL_FILE_HEADER_SIGNATURE[i]) { + throw new InvalidJarHeaderException("Jar " + file.getName() + " do not heave valid header. You can skip this check by -Xignoreheaders"); + } + } + } finally { + s.close(); + } + } + } +} |