3261N/A * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A/* USE_MMAP means mmap the CEN & ENDHDR part of the zip file. */ 0N/A#
define MAXREFS 0xFFFF /* max number of open zip file references */ 0N/A * The ZFILE_* functions exist to provide some platform-independence with 0N/A * respect to file access needs. 0N/A * Opens the named file for reading, returning a ZFILE. 0N/A * This function does not take JNIEnv* and uses CreateFile (instead of 0N/A * CreateFileW). The expectation is that this function will be called only 0N/A * from ZIP_Open_Generic, which in turn is used by the JVM, where we do not 0N/A * need to concern ourselves with wide chars. 0N/A /* Note: O_TRUNC overrides O_CREAT */ 0N/A * Calling JVM_Read will return JVM_IO_INTR when Thread.interrupt is called 0N/A * only on Solaris. Continue reading jar file in this case is the best 0N/A * thing to do since zip file reading is relatively fast and it is very onerous 0N/A * for a interrupted thread to deal with this kind of hidden I/O. However, handling 0N/A * JVM_IO_INTR is tricky and could cause undesired side effect. So we decided 0N/A * Initialize zip file support. Return 0 if successful otherwise -1 0N/A * if could not be initialized. 0N/A // Initialize errno to 0. It may be set later (e.g. during memory 0N/A // allocation) but we can disregard previous values. 0N/A * Reads len bytes of data into buf. 0N/A * Returns 0 if all bytes could be read, otherwise returns -1. 0N/A /* Retry after EINTR (interrupted by signal). 0N/A We depend on the fact that JVM_IO_ERR == -1. */ 0N/A }
else {
/* EOF or IO error */ 0N/A * Reads len bytes of data from the specified offset into buf. 0N/A * Returns 0 if all bytes could be read, otherwise returns -1. 0N/A return -
1;
/* lseek failure. */ 0N/A * Allocates a new zip file object for the specified file name. 0N/A * Returns the zip file object or NULL if not enough memory. 0N/A * Frees all native resources owned by the specified zip file object. 0N/A /* First free any cached jzentry */ 0N/A/* The END header is followed by a variable length comment of size < 64k. */ 1332N/A /* ENDSIG matched, however the size of file comment in it does not 1332N/A match the real size. One "common" cause for this problem is some 1332N/A "extra" bytes are padded at the end of the zipfile. 1332N/A Let's do some extra verification, we don't care about the performance 0N/A * Searches for end of central directory (END) header. The contents of 0N/A * the END header will be read and placed in endbuf. Returns the file 701N/A * position of the END header, otherwise returns -1 if the END header 701N/A * was not found or an error occurred. 0N/A /* Pretend there are some NUL bytes before start of file */ 0N/A return -
1;
/* System error */ 0N/A /* Now scan the block backwards for END header signature */ 701N/A return -
1;
/* END header not found */ 1032N/A * Searches for the ZIP64 end of central directory (END) header. The 1032N/A * contents of the ZIP64 END header will be read and placed in end64buf. 1032N/A * Returns the file position of the ZIP64 END header, otherwise returns 1032N/A * -1 if the END header was not found or an error occurred. 1032N/A * The ZIP format specifies the "position" of each related record as 1032N/A * [zip64 end of central directory record] 1032N/A * [zip64 end of central directory locator] 1032N/A * [end of central directory record] 1032N/A * The offset of zip64 end locator can be calculated from endpos as 1032N/A * The "offset" of zip64 end record is stored in zip64 end locator. 1032N/A return -
1;
// end64 locator not found 1032N/A return -
1;
// end64 record not found 0N/A * Returns a hash code value for a C-style NUL-terminated string. 0N/A * Returns a hash code value for a string of a specified length. 0N/A * Returns true if the specified entry's name begins with the string 0N/A * "META-INF/" irrespective of case. 0N/A for (s =
"META-INF/"; *s !=
'\0'; s++) {
0N/A // Avoid toupper; it's locale-dependent 0N/A if (c >=
'a' && c <=
'z') c +=
'A' -
'a';
0N/A * Increases the capacity of zip->metanames. 0N/A * Returns non-zero in case of allocation error. 0N/A /* double the meta names array */ 0N/A * Adds name to zip->metanames. 0N/A * Returns non-zero in case of allocation error. 0N/A /* current meta name array isn't full yet. */ 0N/A /* No free entries in zip->metanames? */ 0N/A/* Free Zip data allocated by readCEN() */ 0N/A * Counts the number of CEN headers in a central directory extending 0N/A * from BEG to END. Might return a bogus answer if the zip file is 0N/A * corrupt, but will not crash. 0N/A * Reads zip file central directory. Returns the file position of first 701N/A * CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL 701N/A * then the error was a zip format error and zip->msg has the error text. 0N/A * Always pass in -1 for knownTotal; it's used for a recursive call. 0N/A /* Following are unsigned 32-bit */ 0N/A /* Following are unsigned 16-bit */ 0N/A /* Clear previous zip error */ 0N/A /* Get position of END header */ 701N/A return -
1;
/* no END header or system error */ 701N/A if (
endpos == 0)
return 0;
/* only END header present */ 0N/A /* Get position and length of central directory */ 0N/A /* Get position of first local file (LOC) header, taking into 0N/A * account that there may be a stub prefixed to the zip file. */ 2227N/A /* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to 2227N/A * read the jar file contents. However, this greatly increased the perceived 2227N/A * footprint numbers because the mmap'ed pages were adding into the totals shown 2227N/A * by 'ps' and 'top'. We switched to mmaping only the central directory of jar 2227N/A * file while calling 'read' to read the rest of jar file. Here are a list of 2227N/A * reasons apart from above of why we are doing so: 2227N/A * 1. Greatly reduces mmap overhead after startup complete; 2227N/A * 2. Avoids dual path code maintainance; 2227N/A * 3. Greatly reduces risk of address space (not virtual memory) exhaustion. 2227N/A /* When we are not calling recursively, knownTotal is -1. */ 2227N/A /* Mmap the CEN and END part only. We have to figure 2227N/A out the page size in order to make offset to be multiples of 0N/A /* Initialize zip file data structures based on the total number 0N/A * of central directory entries as stored in ENDTOT. Since this 0N/A * is a 2-byte field, but we (and other zip implementations) 0N/A * support approx. 2**31 entries, we do not trust ENDTOT, but 0N/A * treat it only as a strong hint. When we call ourselves 1032N/A * recursively, knownTotal will have the "true" value. 1032N/A * Keep this path alive even with the Zip64 END support added, just 1032N/A * for zip files that have more than 0xffff entries but don't have 0N/A /* Iterate through the entries in the central directory */ 0N/A /* Following are unsigned 16-bit */ 0N/A /* This will only happen if the zip file has an incorrect 0N/A * ENDTOT field, which usually means it contains more than 0N/A /* if the entry is metadata add it to our metadata names */ 0N/A /* Record the CEN offset and the name hash in our hash cell. */ 0N/A /* Add the entry to the hash table */ 0N/A * Opens a zip file with the specified mode. Returns the jzfile object 0N/A * or NULL if an error occurred. If a zip error occurred then *pmsg will 0N/A * be set to the error message text if pmsg != 0. Otherwise, *pmsg will be 5345N/A * set to NULL. Caller is responsible to free the error message. 0N/A /* Clear zip error message */ 0N/A * Returns the jzfile corresponding to the given file name from the cache of 0N/A * zip files, or NULL if the file is not in the cache. If the name is longer 0N/A * than PATH_MAX or a zip error occurred then *pmsg will be set to the error 5345N/A * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller 5345N/A * is responsible to free the error message. 0N/A /* Clear zip error message */ 0N/A * Reads data from the given file descriptor to create a jzfile, puts the 0N/A * jzfile in a cache, and returns that jzfile. Returns NULL in case of error. 0N/A * If a zip error occurs, then *pmsg will be set to the error message text if 5345N/A * pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller is responsible to 6329N/A // Assumption, zfd refers to start of file. Trivially, reuse errbuf. 575N/A if (
len == 0) {
/* zip file is empty */ 0N/A /* An error occurred while trying to read the zip file */ 0N/A /* Set the zip error message */ 0N/A * Opens a zip file for reading. Returns the jzfile object or NULL 0N/A * if an error occurred. If a zip error occurred then *msg will be 0N/A * set to the error message text if msg != 0. Otherwise, *msg will be 5345N/A * set to NULL. Caller doesn't need to free the error message. 0N/A * Closes the specified zip file object. 0N/A /* Still more references so just return */ 0N/A /* No other references so close the file and remove from list */ 0N/A/* Empirically, most CEN headers are smaller than this. */ 0N/A/* A good buffer size when we want to read CEN headers sequentially. */ 0N/A * Return a new initialized jzentry corresponding to a given hash cell. 0N/A * In case of error, returns NULL. 0N/A * We already sanity-checked all the CEN headers for ZIP format errors 0N/A * in readCEN(), so we don't check them again here. 0N/A * The ZIP lock should be held here. 0N/A /* This entry has "extra" data */ 1032N/A // if invalid zip64 extra fields, just skip 0N/A /* This entry has a comment */ 0N/A * Free the given jzentry. 0N/A * In fact we maintain a one-entry cache of the most recently used 0N/A * jzentry for each zip. This optimizes a common access pattern. 0N/A /* Free the previously cached jzentry */ 0N/A * Returns the zip entry corresponding to the specified name, or 0N/A * NULL if not found. 0N/A * This while loop is an optimization where a double lookup 0N/A * for name and name+/ is being performed. The name char 0N/A * array has enough room at the end to try again with a 0N/A * slash appended if the first table lookup does not succeed. 0N/A /* Check the cached entry first */ 0N/A /* Cache hit! Remove and return the cached entry. */ 0N/A * Search down the target hash chain for a cell whose 0N/A * 32 bit hash matches the hashed name. 0N/A * OK, we've found a ZIP entry whose 32 bit hashcode 0N/A * matches the name we're looking for. Try to read 0N/A * its entry information from the CEN. If the CEN 0N/A * name matches the name we're looking for, we're 0N/A * If the names don't match (which should be very rare) 0N/A * we keep searching. 0N/A /* We need to release the lock across the free call */ 0N/A /* Entry found, return it */ 0N/A /* If no real length was passed in, we are done */ 0N/A /* Slash is already there? */ 0N/A /* Add slash and try once more */ 0N/A * Returns the n'th (starting at zero) zip file entry, or NULL if the 0N/A * specified index was out of range. 0N/A * Locks the specified zip file for reading. 0N/A * Unlocks the specified zip file. 0N/A * Returns the offset of the entry data within the zip file. 0N/A * Returns -1 if an error occurred, in which case zip->msg will 0N/A * contain the error text. 0N/A /* The Zip file spec explicitly allows the LOC extra data size to 0N/A * be different from the CEN extra data size, although the JDK 0N/A * never creates such zip files. Since we cannot trust the CEN 0N/A * extra data size, we need to read the LOC to determine the entry 0N/A * data offset. We do this lazily to avoid touching the virtual 0N/A * memory page containing the LOC when initializing jzentry 0N/A * objects. (This speeds up javac by a factor of 10 when the JDK 0N/A * is installed on a very slow filesystem.) 0N/A zip->
msg =
"invalid LOC header (bad signature)";
0N/A * Reads bytes from the specified zip entry. Assumes that the zip 0N/A * file had been previously locked with ZIP_Lock(). Returns the 0N/A * number of bytes read, or -1 if an error occurred. If zip->msg != 0 0N/A * then a zip error occurred and zip->msg contains the error text. 3115N/A * The current implementation does not support reading an entry that 3115N/A * has the size bigger than 2**32 bytes in ONE invocation. 0N/A /* Clear previous zip error */ 0N/A /* Check specified position */ 0N/A zip->
msg =
"ZIP_Read: specified offset out of range";
0N/A /* Check specified length */ 0N/A /* Get file offset to start reading data */ 0N/A zip->
msg =
"ZIP_Read: corrupt zip file: invalid entry size";
0N/A zip->
msg =
"ZIP_Read: error reading zip file";
0N/A/* The maximum size of a stack-allocated buffer. 0N/A * This function is used by the runtime system to load compressed entries 0N/A * from ZIP/JAR files specified in the class path. It is defined here 0N/A * so that it can be dynamically loaded by the runtime if the zip library 3115N/A * The current implementation does not support reading an entry that 3115N/A * has the size bigger than 2**32 bytes in ONE invocation. 0N/A *
msg = 0;
/* Reset error message */ 0N/A *
msg =
"inflateFully: entry not compressed";
0N/A *
msg =
"inflateFully: Unexpected end of file";
0N/A *
msg =
"inflateFully: Unexpected end of stream";
3115N/A * The current implementation does not support reading an entry that 3115N/A * has the size bigger than 2**32 bytes in ONE invocation. 0N/A * Reads a zip file entry into the specified byte array 0N/A * When the method completes, it releases the jzentry. 0N/A * so we have to be careful to maintain the expected behaviour. 0N/A /* Entry is stored */ 0N/A /* These casts suppress a VC++ Internal Compiler Error */ 0N/A /* Entry is compressed */