JarFile.java revision 57995e8186b54515d5a03bf2ab104c3dc247f1b6
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.jar;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-removed
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// import java.io.ByteArrayInputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-removed
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-added
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ByteArrayOutputStream;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-added
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.File;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FilterInputStream;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Enumeration;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.zip.ZipEntry;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.zip.ZipFile;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.archive.util.Util;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code JarFile} is used to read jar entries and their associated data from
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * jar files.
4157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson *
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see JarInputStream
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see JarEntry
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class JarFile extends ZipFile {
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The MANIFEST file name.
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final String META_DIR = "META-INF/"; //$NON-NLS-1$
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Manifest manifest;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ZipEntry manifestEntry;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    JarVerifier verifier;
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-added
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean closed = false;
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-added
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final class JarFileInputStream extends FilterInputStream {
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private long count;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private ZipEntry zipEntry;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private JarVerifier.VerifierEntry entry;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        JarFileInputStream(InputStream is, ZipEntry ze,
7257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                JarVerifier.VerifierEntry e) {
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(is);
7457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            zipEntry = ze;
7557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            count = zipEntry.getSize();
7657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            entry = e;
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int read() throws IOException {
8157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            if (count > 0) {
8257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                int r = super.read();
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (r != -1) {
8457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    entry.write(r);
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    count--;
8657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                } else {
8757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    count = 0;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
8957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                if (count == 0) {
9057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    entry.verify();
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
9257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return r;
9357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            } else {
9457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return -1;
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int read(byte[] buf, int off, int nbytes) throws IOException {
10057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            if (count > 0) {
10157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                int r = super.read(buf, off, nbytes);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (r != -1) {
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    int size = r;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (count < size) {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        size = (int) count;
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
10757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    entry.write(buf, off, size);
10857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    count -= size;
10957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                } else {
11057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    count = 0;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
11257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                if (count == 0) {
11357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                    entry.verify();
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
11557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return r;
11657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            } else {
11757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return -1;
11857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            }
11957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        }
12057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
12157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        // BEGIN android-added
12257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        @Override
12357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        public int available() throws IOException {
12457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            if (count > 0) {
12557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return super.available();
12657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            } else {
12757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                return 0;
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
13057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        // END android-added
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public long skip(long nbytes) throws IOException {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long cnt = 0, rem = 0;
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte[] buf = new byte[4096];
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (cnt < nbytes) {
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int x = read(buf, 0,
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (rem = nbytes - cnt) > buf.length ? buf.length
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : (int) rem);
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (x == -1) {
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return cnt;
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                cnt += x;
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return cnt;
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code JarFile} using the contents of the specified file.
15157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the JAR file as {@link File}.
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the file cannot be read.
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarFile(File file) throws IOException {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(file, true);
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code JarFile} using the contents of the specified file.
16357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the JAR file as {@link File}.
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param verify
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if this JAR file is signed whether it must be verified.
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the file cannot be read.
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarFile(File file, boolean verify) throws IOException {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(file);
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (verify) {
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            verifier = new JarVerifier(file.getPath());
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readMetaEntries();
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code JarFile} using the contents of file.
18157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the JAR file as {@link File}.
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param verify
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if this JAR filed is signed whether it must be verified.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mode
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the mode to use, either {@link ZipFile#OPEN_READ OPEN_READ} or
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@link ZipFile#OPEN_DELETE OPEN_DELETE}.
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If the file cannot be read.
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarFile(File file, boolean verify, int mode) throws IOException {
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(file, mode);
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (verify) {
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            verifier = new JarVerifier(file.getPath());
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readMetaEntries();
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code JarFile} from the contents of the file specified by
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * filename.
20357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param filename
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the file name referring to the JAR file.
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if file name cannot be opened for reading.
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarFile(String filename) throws IOException {
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(filename, true);
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Create a new {@code JarFile} from the contents of the file specified by
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code filename}.
21757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param filename
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the file name referring to the JAR file.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param verify
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if this JAR filed is signed whether it must be verified.
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             If file cannot be opened or read.
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarFile(String filename, boolean verify) throws IOException {
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(filename);
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (verify) {
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            verifier = new JarVerifier(filename);
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        readMetaEntries();
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return an enumeration containing the {@code JarEntrys} contained in this
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code JarFile}.
23657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the {@code Enumeration} containing the JAR entries.
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this {@code JarFile} is closed.
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Enumeration<JarEntry> entries() {
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class JarFileEnumerator implements Enumeration<JarEntry> {
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Enumeration<? extends ZipEntry> ze;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            JarFile jf;
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            JarFileEnumerator(Enumeration<? extends ZipEntry> zenum, JarFile jf) {
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ze = zenum;
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.jf = jf;
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public boolean hasMoreElements() {
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return ze.hasMoreElements();
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public JarEntry nextElement() {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                JarEntry je = new JarEntry(ze.nextElement());
25957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                je.parentJar = jf;
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return je;
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new JarFileEnumerator(super.entries(), this);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the {@code JarEntry} specified by its name or {@code null} if no
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * such entry exists.
26957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the entry in the JAR file.
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the JAR entry defined by the name.
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public JarEntry getJarEntry(String name) {
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (JarEntry) getEntry(name);
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-added
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] getAllBytesFromStreamAndClose(InputStream is) throws IOException {
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ByteArrayOutputStream bs = new ByteArrayOutputStream();
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte[] buf = new byte[666];
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int iRead; int off;
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (is.available() > 0) {
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                iRead = is.read(buf, 0, buf.length);
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (iRead > 0)
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    bs.write(buf, 0, iRead);
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            is.close();
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return bs.toByteArray();
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-added
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the {@code Manifest} object associated with this {@code JarFile}
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or {@code null} if no MANIFEST entry exists.
30057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the MANIFEST.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs reading the MANIFEST file.
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the jar file is closed.
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see Manifest
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Manifest getManifest() throws IOException {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-added
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (closed) {
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalStateException("JarFile has been closed.");
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-added
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (manifest != null) {
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return manifest;
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // BEGIN android-modified
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InputStream is = super.getInputStream(manifestEntry);
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (verifier != null) {
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                verifier.addMetaEntry(manifestEntry.getName(), getAllBytesFromStreamAndClose(is));
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                is = super.getInputStream(manifestEntry);
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // END android-modified
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                manifest = new Manifest(is, verifier != null);
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } finally {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                is.close();
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            manifestEntry = null;
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch(NullPointerException e) {
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            manifestEntry = null;
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return manifest;
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readMetaEntries() throws IOException {
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ZipEntry[] metaEntries = getMetaEntriesImpl(null);
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int dirLength = META_DIR.length();
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean signed = false;
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null != metaEntries) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (ZipEntry entry : metaEntries) {
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String entryName = entry.getName();
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (manifestEntry == null
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && manifest == null
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && Util.ASCIIIgnoreCaseRegionMatches(entryName,
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                dirLength, MANIFEST_NAME, dirLength,
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                MANIFEST_NAME.length() - dirLength)) {
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    manifestEntry = entry;
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (verifier == null) {
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
35557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                } else if (verifier != null
35657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                        && entryName.length() > dirLength
35757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                        && (Util.ASCIIIgnoreCaseRegionMatches(entryName,
35857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                                entryName.length() - 3, ".SF", 0, 3) //$NON-NLS-1$
35957995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                                || Util.ASCIIIgnoreCaseRegionMatches(entryName,
36057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                                        entryName.length() - 4, ".DSA", 0, 4) //$NON-NLS-1$
36157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                        || Util.ASCIIIgnoreCaseRegionMatches(entryName,
36257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                                entryName.length() - 4, ".RSA", 0, 4))) { //$NON-NLS-1$
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    signed = true;
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    InputStream is = super.getInputStream(entry);
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // BEGIN android-modified
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    byte[] buf = getAllBytesFromStreamAndClose(is);
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // END android-modified
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    verifier.addMetaEntry(entryName, buf);
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!signed) {
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            verifier = null;
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return an {@code InputStream} for reading the decompressed contents of
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ZIP entry.
38057995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param ze
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the ZIP entry to be read.
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the input stream to read from.
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurred while creating the input stream.
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InputStream getInputStream(ZipEntry ze) throws IOException {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (manifestEntry != null) {
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            getManifest();
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (verifier != null) {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            verifier.setManifest(getManifest());
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (manifest != null) {
39557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson                verifier.mainAttributesEnd = manifest.getMainAttributesEnd();
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (verifier.readCertificates()) {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                verifier.removeMetaEntries();
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (manifest != null) {
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    manifest.removeChunks();
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!verifier.isSignedJar()) {
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    verifier = null;
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InputStream in = super.getInputStream(ze);
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (in == null) {
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
41157995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        if (verifier == null || ze.getSize() == -1) {
41257995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            return in;
41357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        }
41457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        JarVerifier.VerifierEntry entry = verifier.initEntry(ze.getName());
41557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        if (entry == null) {
41657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson            return in;
41757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        }
41857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        return new JarFileInputStream(in, ze, entry);
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return the {@code JarEntry} specified by name or {@code null} if no such
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * entry exists.
42457995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the entry in the JAR file.
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the ZIP entry extracted.
42857995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     */
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ZipEntry getEntry(String name) {
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ZipEntry ze = super.getEntry(name);
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ze == null) {
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ze;
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        JarEntry je = new JarEntry(ze);
43657995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson        je.parentJar = this;
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return je;
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-modified
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ZipEntry[] getMetaEntriesImpl(byte[] buf) {
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int n = 0;
44357995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        List<ZipEntry> list = new ArrayList<ZipEntry>();
44557995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Enumeration<? extends ZipEntry> allEntries = entries();
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (allEntries.hasMoreElements()) {
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ZipEntry ze = allEntries.nextElement();
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ze.getName().startsWith("META-INF/") && ze.getName().length() > 9) {
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                list.add(ze);
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (list.size() != 0) {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ZipEntry[] result = new ZipEntry[list.size()];
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            list.toArray(result);
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result;
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-modified
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // BEGIN android-added
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this {@code JarFile}.
46757995e8186b54515d5a03bf2ab104c3dc247f1b6Jesse Wilson     *
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs.
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super.close();
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        closed = true;
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // END android-added
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
479