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