11d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 81d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 101d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.util.jar; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.File; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FilterInputStream; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream; 241d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilsonimport java.util.ArrayList; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Enumeration; 261d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilsonimport java.util.List; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.zip.ZipEntry; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.zip.ZipFile; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 301d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilsonimport org.apache.harmony.archive.internal.nls.Messages; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.archive.util.Util; 321d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilsonimport org.apache.harmony.luni.util.InputStreamHelper; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code JarFile} is used to read jar entries and their associated data from 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * jar files. 37407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see JarInputStream 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see JarEntry 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class JarFile extends ZipFile { 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The MANIFEST file name. 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; //$NON-NLS-1$ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // The directory containing the manifest. 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final String META_DIR = "META-INF/"; //$NON-NLS-1$ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 511d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // The manifest after it has been read from the JAR. 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Manifest manifest; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 541d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // The entry for the MANIFEST.MF file before it is read. 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ZipEntry manifestEntry; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarVerifier verifier; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean closed = false; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final class JarFileInputStream extends FilterInputStream { 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private long count; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ZipEntry zipEntry; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private JarVerifier.VerifierEntry entry; 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 684949c14402562af123745d59020cd4fc5eb565cbUrs Grob private boolean done = false; 694949c14402562af123745d59020cd4fc5eb565cbUrs Grob 70407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson JarFileInputStream(InputStream is, ZipEntry ze, 71407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson JarVerifier.VerifierEntry e) { 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(is); 73407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson zipEntry = ze; 74407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson count = zipEntry.getSize(); 75407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson entry = e; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read() throws IOException { 804949c14402562af123745d59020cd4fc5eb565cbUrs Grob if (done) { 814949c14402562af123745d59020cd4fc5eb565cbUrs Grob return -1; 824949c14402562af123745d59020cd4fc5eb565cbUrs Grob } 83407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (count > 0) { 84407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson int r = super.read(); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (r != -1) { 86407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson entry.write(r); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count--; 88407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } else { 89407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson count = 0; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (count == 0) { 924949c14402562af123745d59020cd4fc5eb565cbUrs Grob done = true; 93407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson entry.verify(); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return r; 96407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } else { 974949c14402562af123745d59020cd4fc5eb565cbUrs Grob done = true; 984949c14402562af123745d59020cd4fc5eb565cbUrs Grob entry.verify(); 99407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return -1; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int read(byte[] buf, int off, int nbytes) throws IOException { 1054949c14402562af123745d59020cd4fc5eb565cbUrs Grob if (done) { 1064949c14402562af123745d59020cd4fc5eb565cbUrs Grob return -1; 1074949c14402562af123745d59020cd4fc5eb565cbUrs Grob } 108407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (count > 0) { 109407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson int r = super.read(buf, off, nbytes); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (r != -1) { 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = r; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count < size) { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = (int) count; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson entry.write(buf, off, size); 116407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson count -= size; 117407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } else { 118407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson count = 0; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (count == 0) { 1214949c14402562af123745d59020cd4fc5eb565cbUrs Grob done = true; 122407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson entry.verify(); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return r; 125407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } else { 1264949c14402562af123745d59020cd4fc5eb565cbUrs Grob done = true; 1274949c14402562af123745d59020cd4fc5eb565cbUrs Grob entry.verify(); 128407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return -1; 129407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } 130407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } 131407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson 132407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson @Override 133407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson public int available() throws IOException { 1344949c14402562af123745d59020cd4fc5eb565cbUrs Grob if (done) { 135407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return 0; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1374949c14402562af123745d59020cd4fc5eb565cbUrs Grob return super.available(); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long skip(long nbytes) throws IOException { 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long cnt = 0, rem = 0; 1431d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson byte[] buf = new byte[(int)Math.min(nbytes, 2048L)]; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (cnt < nbytes) { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int x = read(buf, 0, 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (rem = nbytes - cnt) > buf.length ? buf.length 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : (int) rem); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (x == -1) { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return cnt; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cnt += x; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return cnt; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new {@code JarFile} using the contents of the specified file. 159407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the JAR file as {@link File}. 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the file cannot be read. 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile(File file) throws IOException { 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(file, true); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new {@code JarFile} using the contents of the specified file. 171407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the JAR file as {@link File}. 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param verify 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if this JAR file is signed whether it must be verified. 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the file cannot be read. 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile(File file, boolean verify) throws IOException { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(file); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verify) { 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier = new JarVerifier(file.getPath()); 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readMetaEntries(); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new {@code JarFile} using the contents of file. 189407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the JAR file as {@link File}. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param verify 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if this JAR filed is signed whether it must be verified. 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param mode 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the mode to use, either {@link ZipFile#OPEN_READ OPEN_READ} or 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link ZipFile#OPEN_DELETE OPEN_DELETE}. 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the file cannot be read. 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile(File file, boolean verify, int mode) throws IOException { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(file, mode); 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verify) { 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier = new JarVerifier(file.getPath()); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readMetaEntries(); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new {@code JarFile} from the contents of the file specified by 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * filename. 211407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param filename 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the file name referring to the JAR file. 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if file name cannot be opened for reading. 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile(String filename) throws IOException { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(filename, true); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a new {@code JarFile} from the contents of the file specified by 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code filename}. 224407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param filename 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the file name referring to the JAR file. 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param verify 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if this JAR filed is signed whether it must be verified. 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If file cannot be opened or read. 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarFile(String filename, boolean verify) throws IOException { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(filename); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verify) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier = new JarVerifier(filename); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project readMetaEntries(); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an enumeration containing the {@code JarEntrys} contained in this 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code JarFile}. 243407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the {@code Enumeration} containing the JAR entries. 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalStateException 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if this {@code JarFile} is closed. 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Enumeration<JarEntry> entries() { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project class JarFileEnumerator implements Enumeration<JarEntry> { 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<? extends ZipEntry> ze; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFile jf; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarFileEnumerator(Enumeration<? extends ZipEntry> zenum, JarFile jf) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ze = zenum; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.jf = jf; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean hasMoreElements() { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ze.hasMoreElements(); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarEntry nextElement() { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarEntry je = new JarEntry(ze.nextElement()); 266407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson je.parentJar = jf; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return je; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new JarFileEnumerator(super.entries(), this); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the {@code JarEntry} specified by its name or {@code null} if no 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * such entry exists. 276407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param name 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the entry in the JAR file. 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the JAR entry defined by the name. 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public JarEntry getJarEntry(String name) { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (JarEntry) getEntry(name); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the {@code Manifest} object associated with this {@code JarFile} 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or {@code null} if no MANIFEST entry exists. 288407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the MANIFEST. 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an error occurs reading the MANIFEST file. 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalStateException 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the jar file is closed. 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see Manifest 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Manifest getManifest() throws IOException { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (closed) { 2981d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // archive.35=JarFile has been closed 2991d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson throw new IllegalStateException(Messages.getString("archive.35")); //$NON-NLS-1$ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (manifest != null) { 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return manifest; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputStream is = super.getInputStream(manifestEntry); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verifier != null) { 3071d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson verifier.addMetaEntry(manifestEntry.getName(), 3081d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson InputStreamHelper.readFullyAndClose(is)); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is = super.getInputStream(manifestEntry); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project manifest = new Manifest(is, verifier != null); 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } finally { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project is.close(); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3161d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson manifestEntry = null; // Can discard the entry now. 3171d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson } catch (NullPointerException e) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project manifestEntry = null; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return manifest; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3231d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson /** 3241d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * Called by the JarFile constructors, this method reads the contents of the 3251d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * file's META-INF/ directory and picks out the MANIFEST.MF file and 3261d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * verifier signature files if they exist. Any signature files found are 3271d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * registered with the verifier. 3281d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * 3291d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * @throws IOException 3301d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * if there is a problem reading the jar file entries. 3311d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson */ 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void readMetaEntries() throws IOException { 3331d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // Get all meta directory entries 3341d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson ZipEntry[] metaEntries = getMetaEntriesImpl(); 3351d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (metaEntries == null) { 3361d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson verifier = null; 3371d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson return; 3381d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson } 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean signed = false; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3421d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson for (ZipEntry entry : metaEntries) { 3431d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson String entryName = entry.getName(); 3441d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // Is this the entry for META-INF/MANIFEST.MF ? 3451d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (manifestEntry == null 3461d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson && Util.asciiEqualsIgnoreCase(MANIFEST_NAME, entryName)) { 3471d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson manifestEntry = entry; 3481d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // If there is no verifier then we don't need to look any further. 3491d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (verifier == null) { 3501d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson break; 3511d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson } 3521d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson } else { 3531d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // Is this an entry that the verifier needs? 3541d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (verifier != null 3551d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson && (Util.asciiEndsWithIgnoreCase(entryName, ".SF") 3561d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson || Util.asciiEndsWithIgnoreCase(entryName, ".DSA") 3571d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson || Util.asciiEndsWithIgnoreCase(entryName, ".RSA"))) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signed = true; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputStream is = super.getInputStream(entry); 3601d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson byte[] buf = InputStreamHelper.readFullyAndClose(is); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier.addMetaEntry(entryName, buf); 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3651d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson 3661d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson // If there were no signature files, then no verifier work to do. 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!signed) { 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier = null; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return an {@code InputStream} for reading the decompressed contents of 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ZIP entry. 375407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ze 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the ZIP entry to be read. 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the input stream to read from. 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an error occurred while creating the input stream. 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InputStream getInputStream(ZipEntry ze) throws IOException { 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (manifestEntry != null) { 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getManifest(); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verifier != null) { 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier.setManifest(getManifest()); 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (manifest != null) { 390407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson verifier.mainAttributesEnd = manifest.getMainAttributesEnd(); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verifier.readCertificates()) { 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier.removeMetaEntries(); 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (manifest != null) { 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project manifest.removeChunks(); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!verifier.isSignedJar()) { 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifier = null; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InputStream in = super.getInputStream(ze); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (in == null) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 406407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (verifier == null || ze.getSize() == -1) { 407407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return in; 408407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } 409407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson JarVerifier.VerifierEntry entry = verifier.initEntry(ze.getName()); 410407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson if (entry == null) { 411407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return in; 412407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson } 413407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson return new JarFileInputStream(in, ze, entry); 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the {@code JarEntry} specified by name or {@code null} if no such 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry exists. 419407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param name 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the entry in the JAR file. 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the ZIP entry extracted. 423407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson */ 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ZipEntry getEntry(String name) { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ZipEntry ze = super.getEntry(name); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ze == null) { 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ze; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JarEntry je = new JarEntry(ze); 431407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson je.parentJar = this; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return je; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4351d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson /** 4361d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * Returns all the ZipEntry's that relate to files in the 4371d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * JAR's META-INF directory. 4381d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * 4391d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson * @return the list of ZipEntry's or {@code null} if there are none. 4401d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson */ 4411d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson private ZipEntry[] getMetaEntriesImpl() { 4421d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson List<ZipEntry> list = new ArrayList<ZipEntry>(8); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Enumeration<? extends ZipEntry> allEntries = entries(); 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (allEntries.hasMoreElements()) { 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ZipEntry ze = allEntries.nextElement(); 4461d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (ze.getName().startsWith(META_DIR) 4471d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson && ze.getName().length() > META_DIR.length()) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project list.add(ze); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4511d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson if (list.size() == 0) { 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 4541d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson ZipEntry[] result = new ZipEntry[list.size()]; 4551d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson list.toArray(result); 4561d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson return result; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Closes this {@code JarFile}. 461407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson * 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IOException 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if an error occurs. 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void close() throws IOException { 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super.close(); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closed = true; 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 471