Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/java/util/zip/ZipFile.c
38830 views
/*1* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* Native method support for java.util.zip.ZipFile27*/2829#include <stdio.h>30#include <stdlib.h>31#include <string.h>32#include <errno.h>33#include <ctype.h>34#include <assert.h>35#include "jlong.h"36#include "jvm.h"37#include "jni.h"38#include "jni_util.h"39#include "zip_util.h"40#ifdef WIN3241#include "io_util_md.h"42#else43#include "io_util.h"44#endif4546#include "java_util_zip_ZipFile.h"47#include "java_util_jar_JarFile.h"4849#define DEFLATED 850#define STORED 05152static jfieldID jzfileID;5354static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;55static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;5657JNIEXPORT void JNICALL58Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)59{60jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");61assert(jzfileID != 0);62}6364static void65ThrowZipException(JNIEnv *env, const char *msg)66{67jstring s = NULL;68jobject x;6970if (msg != NULL) {71s = JNU_NewStringPlatform(env, msg);72}73if (s != NULL) {74x = JNU_NewObjectByName(env,75"java/util/zip/ZipException",76"(Ljava/lang/String;)V", s);77if (x != NULL) {78(*env)->Throw(env, x);79}80}81}8283JNIEXPORT jlong JNICALL84Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,85jint mode, jlong lastModified,86jboolean usemmap)87{88const char *path = JNU_GetStringPlatformChars(env, name, 0);89char *msg = 0;90jlong result = 0;91int flag = 0;92jzfile *zip = 0;9394if (mode & OPEN_READ) flag |= O_RDONLY;95if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;9697if (path != 0) {98zip = ZIP_Get_From_Cache(path, &msg, lastModified);99if (zip == 0 && msg == 0) {100ZFILE zfd = 0;101#ifdef WIN32102zfd = winFileHandleOpen(env, name, flag);103if (zfd == -1) {104/* Exception already pending. */105goto finally;106}107#else108zfd = JVM_Open(path, flag, 0);109if (zfd < 0) {110throwFileNotFoundException(env, name);111goto finally;112}113#endif114zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);115}116117if (zip != 0) {118result = ptr_to_jlong(zip);119} else if (msg != 0) {120ThrowZipException(env, msg);121free(msg);122} else if (errno == ENOMEM) {123JNU_ThrowOutOfMemoryError(env, 0);124} else {125ThrowZipException(env, "error in opening zip file");126}127finally:128JNU_ReleaseStringPlatformChars(env, name, path);129}130return result;131}132133JNIEXPORT jint JNICALL134Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)135{136jzfile *zip = jlong_to_ptr(zfile);137138return zip->total;139}140141JNIEXPORT jboolean JNICALL142Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)143{144jzfile *zip = jlong_to_ptr(zfile);145146return zip->locsig;147}148149JNIEXPORT void JNICALL150Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)151{152ZIP_Close(jlong_to_ptr(zfile));153}154155JNIEXPORT jlong JNICALL156Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,157jbyteArray name, jboolean addSlash)158{159#define MAXNAME 1024160jzfile *zip = jlong_to_ptr(zfile);161jsize ulen = (*env)->GetArrayLength(env, name);162char buf[MAXNAME+2], *path;163jzentry *ze;164165if (ulen > MAXNAME) {166path = malloc(ulen + 2);167if (path == 0) {168JNU_ThrowOutOfMemoryError(env, 0);169return 0;170}171} else {172path = buf;173}174(*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);175path[ulen] = '\0';176ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);177if (path != buf) {178free(path);179}180return ptr_to_jlong(ze);181}182183JNIEXPORT void JNICALL184Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,185jlong zentry)186{187jzfile *zip = jlong_to_ptr(zfile);188jzentry *ze = jlong_to_ptr(zentry);189ZIP_FreeEntry(zip, ze);190}191192JNIEXPORT jlong JNICALL193Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,194jint n)195{196jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);197return ptr_to_jlong(ze);198}199200JNIEXPORT jint JNICALL201Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)202{203jzentry *ze = jlong_to_ptr(zentry);204return ze->csize != 0 ? DEFLATED : STORED;205}206207JNIEXPORT jint JNICALL208Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)209{210jzentry *ze = jlong_to_ptr(zentry);211return ze->flag;212}213214JNIEXPORT jlong JNICALL215Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)216{217jzentry *ze = jlong_to_ptr(zentry);218return ze->csize != 0 ? ze->csize : ze->size;219}220221JNIEXPORT jlong JNICALL222Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)223{224jzentry *ze = jlong_to_ptr(zentry);225return ze->size;226}227228JNIEXPORT jlong JNICALL229Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)230{231jzentry *ze = jlong_to_ptr(zentry);232return (jlong)ze->time & 0xffffffffUL;233}234235JNIEXPORT jlong JNICALL236Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)237{238jzentry *ze = jlong_to_ptr(zentry);239return (jlong)ze->crc & 0xffffffffUL;240}241242JNIEXPORT jbyteArray JNICALL243Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,244jclass cls,245jlong zfile)246{247jzfile *zip = jlong_to_ptr(zfile);248jbyteArray jba = NULL;249250if (zip->comment != NULL) {251if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)252return NULL;253(*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);254}255return jba;256}257258JNIEXPORT jbyteArray JNICALL259Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,260jclass cls,261jlong zentry, jint type)262{263jzentry *ze = jlong_to_ptr(zentry);264int len = 0;265jbyteArray jba = NULL;266switch (type) {267case java_util_zip_ZipFile_JZENTRY_NAME:268if (ze->name != 0) {269len = (int)ze->nlen;270if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)271break;272(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);273}274break;275case java_util_zip_ZipFile_JZENTRY_EXTRA:276if (ze->extra != 0) {277unsigned char *bp = (unsigned char *)&ze->extra[0];278len = (bp[0] | (bp[1] << 8));279if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)280break;281(*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);282}283break;284case java_util_zip_ZipFile_JZENTRY_COMMENT:285if (ze->comment != 0) {286len = (int)strlen(ze->comment);287if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)288break;289(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);290}291break;292}293return jba;294}295296JNIEXPORT jint JNICALL297Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,298jlong zentry, jlong pos, jbyteArray bytes,299jint off, jint len)300{301jzfile *zip = jlong_to_ptr(zfile);302char *msg;303304#define BUFSIZE 8192305/* copy via tmp stack buffer: */306jbyte buf[BUFSIZE];307308if (len > BUFSIZE) {309len = BUFSIZE;310}311312ZIP_Lock(zip);313len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);314msg = zip->msg;315ZIP_Unlock(zip);316if (len != -1) {317(*env)->SetByteArrayRegion(env, bytes, off, len, buf);318}319320if (len == -1) {321if (msg != 0) {322ThrowZipException(env, msg);323} else {324char errmsg[128];325sprintf(errmsg, "errno: %d, error: %s\n",326errno, "Error reading ZIP file");327JNU_ThrowIOExceptionWithLastError(env, errmsg);328}329}330331return len;332}333334/*335* Returns an array of strings representing the names of all entries336* that begin with "META-INF/" (case ignored). This native method is337* used in JarFile as an optimization when looking up manifest and338* signature file entries. Returns null if no entries were found.339*/340JNIEXPORT jobjectArray JNICALL341Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)342{343jlong zfile = (*env)->GetLongField(env, obj, jzfileID);344jzfile *zip;345int i, count;346jobjectArray result = 0;347348if (zfile == 0) {349JNU_ThrowByName(env,350"java/lang/IllegalStateException", "zip file closed");351return NULL;352}353zip = jlong_to_ptr(zfile);354355/* count the number of valid ZIP metanames */356count = 0;357if (zip->metanames != 0) {358for (i = 0; i < zip->metacount; i++) {359if (zip->metanames[i] != 0) {360count++;361}362}363}364365/* If some names were found then build array of java strings */366if (count > 0) {367jclass cls = JNU_ClassString(env);368CHECK_NULL_RETURN(cls, NULL);369result = (*env)->NewObjectArray(env, count, cls, 0);370CHECK_NULL_RETURN(result, NULL);371if (result != 0) {372for (i = 0; i < count; i++) {373jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);374if (str == 0) {375break;376}377(*env)->SetObjectArrayElement(env, result, i, str);378(*env)->DeleteLocalRef(env, str);379}380}381}382return result;383}384385JNIEXPORT jstring JNICALL386Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)387{388jzfile *zip = jlong_to_ptr(zfile);389char *msg = zip->msg;390if (msg == NULL) {391return NULL;392}393return JNU_NewStringPlatform(env, msg);394}395396397