151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.jar;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.zip.*;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ManifestEntryVerifier;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.JarIndex;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The <code>JarInputStream</code> class is used to read the contents of
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a JAR file from any input stream. It extends the class
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>java.util.zip.ZipInputStream</code> with support for reading
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an optional <code>Manifest</code> entry. The <code>Manifest</code>
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * can be used to store meta-information about the JAR file and its entries.
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author  David Connelly
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     Manifest
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     java.util.zip.ZipInputStream
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since   1.2
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass JarInputStream extends ZipInputStream {
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Manifest man;
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private JarEntry first;
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private JarVerifier jv;
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private ManifestEntryVerifier mev;
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final boolean doVerify;
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean tryManifest;
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a new <code>JarInputStream</code> and reads the optional
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * manifest. If a manifest is present, also attempts to verify
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the signatures if the JarInputStream is signed.
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param in the actual input stream
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O error has occurred
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public JarInputStream(InputStream in) throws IOException {
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(in, true);
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a new <code>JarInputStream</code> and reads the optional
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * manifest. If a manifest is present and verify is true, also attempts
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to verify the signatures if the JarInputStream is signed.
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param in the actual input stream
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param verify whether or not to verify the JarInputStream if
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * it is signed.
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O error has occurred
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public JarInputStream(InputStream in, boolean verify) throws IOException {
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(in);
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.doVerify = verify;
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // This implementation assumes the META-INF/MANIFEST.MF entry
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // should be either the first or the second entry (when preceded
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // by the dir META-INF/). It skips the META-INF/ and then
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // "consumes" the MANIFEST.MF to initialize the Manifest object.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        JarEntry e = (JarEntry)super.getNextEntry();
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            e = (JarEntry)super.getNextEntry();
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        first = checkManifest(e);
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private JarEntry checkManifest(JarEntry e)
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            man = new Manifest();
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            byte bytes[] = getBytes(new BufferedInputStream(this));
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            man.read(new ByteArrayInputStream(bytes));
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            closeEntry();
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (doVerify) {
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                jv = new JarVerifier(bytes);
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                mev = new ManifestEntryVerifier(man);
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (JarEntry)super.getNextEntry();
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return e;
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private byte[] getBytes(InputStream is)
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        byte[] buffer = new byte[8192];
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n;
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ((n = is.read(buffer, 0, buffer.length)) != -1) {
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            baos.write(buffer, 0, n);
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return baos.toByteArray();
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the <code>Manifest</code> for this JAR file, or
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>null</code> if none.
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the <code>Manifest</code> for this JAR file, or
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         <code>null</code> if none.
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Manifest getManifest() {
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return man;
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads the next ZIP file entry and positions the stream at the
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * beginning of the entry data. If verification has been enabled,
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * any invalid signature detected while positioning the stream for
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the next entry will result in an exception.
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ZipException if a ZIP file error has occurred
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O error has occurred
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if any of the jar file entries
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         are incorrectly signed.
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public ZipEntry getNextEntry() throws IOException {
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        JarEntry e;
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (first == null) {
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            e = (JarEntry)super.getNextEntry();
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (tryManifest) {
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                e = checkManifest(e);
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                tryManifest = false;
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            e = first;
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (first.getName().equalsIgnoreCase(JarIndex.INDEX_NAME))
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                tryManifest = true;
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            first = null;
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (jv != null && e != null) {
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // At this point, we might have parsed all the meta-inf
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // entries and have nothing to verify. If we have
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // nothing to verify, get rid of the JarVerifier object.
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (jv.nothingToVerify() == true) {
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                jv = null;
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                mev = null;
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                jv.beginEntry(e, mev);
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return e;
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads the next JAR file entry and positions the stream at the
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * beginning of the entry data. If verification has been enabled,
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * any invalid signature detected while positioning the stream for
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the next entry will result in an exception.
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the next JAR file entry, or null if there are no more entries
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ZipException if a ZIP file error has occurred
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O error has occurred
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if any of the jar file entries
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         are incorrectly signed.
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public JarEntry getNextJarEntry() throws IOException {
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (JarEntry)getNextEntry();
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads from the current JAR file entry into an array of bytes.
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If <code>len</code> is not zero, the method
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * blocks until some input is available; otherwise, no
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * bytes are read and <code>0</code> is returned.
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If verification has been enabled, any invalid signature
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on the current entry will be reported at some point before the
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * end of the entry is reached.
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param b the buffer into which the data is read
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param off the start offset in the destination array <code>b</code>
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param len the maximum number of bytes to read
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the actual number of bytes read, or -1 if the end of the
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         entry is reached
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>len</code> is negative, or <code>len</code> is greater than
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>b.length - off</code>
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ZipException if a ZIP file error has occurred
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O error has occurred
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if any of the jar file entries
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         are incorrectly signed.
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(byte[] b, int off, int len) throws IOException {
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n;
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (first == null) {
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n = super.read(b, off, len);
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n = -1;
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (jv != null) {
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            jv.update(n, b, off, len, mev);
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n;
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a new <code>JarEntry</code> (<code>ZipEntry</code>) for the
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * specified JAR file entry name. The manifest attributes of
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the specified JAR file entry name will be copied to the new
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <CODE>JarEntry</CODE>.
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name the name of the JAR/ZIP file entry
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the <code>JarEntry</code> object just created
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected ZipEntry createZipEntry(String name) {
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        JarEntry e = new JarEntry(name);
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (man != null) {
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            e.attr = man.getAttributes(name);
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return e;
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
234