< prev index next >
src/share/native/com/sun/java/util/jar/pack/jni.cpp
Print this page
rev 1357 : 6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
Summary: Removal of compiler warnings and fixing of assert logic.
Reviewed-by: jrose, ksrini, bristor
rev 1360 : 7166955: (pack200) JNI_GetCreatedJavaVMs needs additional checking
Reviewed-by: alanb, dholmes, ksrini
rev 1361 : 8029177: [Parfait] warnings from b117 for jdk.src.share.native.com.sun.java.util.jar: JNI exception pending
Summary: Additional review by Chris Ries
Reviewed-by: jfranck, ksrini
rev 1364 : 8074839: Resolve disabled warnings for libunpack and the unpack200 binary
Reviewed-by: dholmes, ksrini
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -57,10 +57,49 @@
static char* dbg = null;
#define THROW_IOE(x) JNU_ThrowIOException(env,x)
+#define CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(CERVTI_exception, CERVTI_message) \
+ do { \
+ if ((env)->ExceptionOccurred()) { \
+ THROW_IOE(CERVTI_message); \
+ return; \
+ } \
+ if ((CERVTI_exception) == NULL) { \
+ THROW_IOE(CERVTI_message); \
+ return; \
+ } \
+ } while (JNI_FALSE)
+
+
+#define CHECK_EXCEPTION_RETURN_VALUE(CERL_exception, CERL_return_value) \
+ do { \
+ if ((env)->ExceptionOccurred()) { \
+ return CERL_return_value; \
+ } \
+ if ((CERL_exception) == NULL) { \
+ return CERL_return_value; \
+ } \
+ } while (JNI_FALSE)
+
+
+// If these useful macros aren't defined in jni_util.h then define them here
+#ifndef CHECK_NULL_RETURN
+#define CHECK_NULL_RETURN(x, y) \
+ do { \
+ if ((x) == NULL) return (y); \
+ } while (JNI_FALSE)
+#endif
+
+#ifndef CHECK_EXCEPTION_RETURN
+#define CHECK_EXCEPTION_RETURN(env, y) \
+ do { \
+ if ((*env)->ExceptionCheck(env)) return (y); \
+ } while (JNI_FALSE)
+#endif
+
static jlong read_input_via_jni(unpacker* self,
void* buf, jlong minlen, jlong maxlen);
static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
unpacker* uPtr;
@@ -74,28 +113,34 @@
return null;
}
//fprintf(stderr, "get_unpacker(%p) uPtr=%p initializing\n", pObj, uPtr);
uPtr->init(read_input_via_jni);
uPtr->jniobj = (void*) env->NewGlobalRef(pObj);
- env->SetLongField(pObj, unpackerPtrFID, (jlong)uPtr);
+ env->SetLongField(pObj, unpackerPtrFID, ptr2jlong(uPtr));
}
uPtr->jnienv = env; // keep refreshing this in case of MT access
return uPtr;
}
// This is the harder trick: Pull the current state out of mid-air.
static unpacker* get_unpacker() {
//fprintf(stderr, "get_unpacker()\n");
JavaVM* vm = null;
- JNI_GetCreatedJavaVMs(&vm, 1, null);
+ jsize nVM = 0;
+ jint retval = JNI_GetCreatedJavaVMs(&vm, 1, &nVM);
+ // other VM implements may differ, thus for correctness, we need these checks
+ if (retval != JNI_OK || nVM != 1)
+ return null;
void* envRaw = null;
vm->GetEnv(&envRaw, JNI_VERSION_1_1);
JNIEnv* env = (JNIEnv*) envRaw;
//fprintf(stderr, "get_unpacker() env=%p\n", env);
- if (env == null)
- return null;
+ CHECK_NULL_RETURN(env, NULL);
jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
+ // We should check upon the known non-null variable because here we want to check
+ // only for pending exceptions. If pObj is null we'll deal with it later.
+ CHECK_EXCEPTION_RETURN_VALUE(env, NULL);
//fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
if (pObj != null) {
// Got pObj and env; now do it the easy way.
return get_unpacker(env, pObj);
}
@@ -134,45 +179,42 @@
#ifndef PRODUCT
dbg = getenv("DEBUG_ATTACH");
while( dbg != null) { sleep(10); }
#endif
NIclazz = (jclass) env->NewGlobalRef(clazz);
+
unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
+ CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(unpackerPtrFID, ERROR_INIT);
+
currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
"()Ljava/lang/Object;");
+ CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(currentInstMID, ERROR_INIT);
+
readInputMID = env->GetMethodID(clazz, "readInputFn",
"(Ljava/nio/ByteBuffer;J)J");
+ CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(readInputMID, ERROR_INIT);
getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
-
- if (unpackerPtrFID == null ||
- currentInstMID == null ||
- readInputMID == null ||
- NIclazz == null ||
- getUnpackerPtrMID == null) {
- THROW_IOE("cannot init class members");
- }
+ CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(getUnpackerPtrMID, ERROR_INIT);
}
JNIEXPORT jlong JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
jobject pBuf, jlong offset) {
// try to get the unpacker pointer the hard way first, we do this to ensure
// valid object pointers and env is intact, if not now is good time to bail.
unpacker* uPtr = get_unpacker();
//fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr);
- if (uPtr == null) {
- return -1;
- }
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, -1);
// redirect our io to the default log file or whatever.
uPtr->redirect_stdio();
void* buf = null;
size_t buflen = 0;
if (pBuf != null) {
buf = env->GetDirectBufferAddress(pBuf);
- buflen = env->GetDirectBufferCapacity(pBuf);
+ buflen = (size_t)env->GetDirectBufferCapacity(pBuf);
if (buflen == 0) buf = null;
if (buf == null) { THROW_IOE(ERROR_INTERNAL); return 0; }
if ((size_t)offset >= buflen)
{ buf = null; buflen = 0; }
else
@@ -200,56 +242,64 @@
JNIEXPORT jboolean JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj,
jobjectArray pParts) {
unpacker* uPtr = get_unpacker(env, pObj);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, false);
unpacker::file* filep = uPtr->get_next_file();
if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message());
return false;
}
- if (filep == null) {
- return false; // end of the sequence
- }
+ CHECK_NULL_RETURN(filep, false);
assert(filep == &uPtr->cur_file);
int pidx = 0, iidx = 0;
jintArray pIntParts = (jintArray) env->GetObjectArrayElement(pParts, pidx++);
+ CHECK_EXCEPTION_RETURN_VALUE(pIntParts, false);
jint* intParts = env->GetIntArrayElements(pIntParts, null);
intParts[iidx++] = (jint)( (julong)filep->size >> 32 );
intParts[iidx++] = (jint)( (julong)filep->size >> 0 );
intParts[iidx++] = filep->modtime;
intParts[iidx++] = filep->deflate_hint() ? 1 : 0;
env->ReleaseIntArrayElements(pIntParts, intParts, JNI_COMMIT);
-
- env->SetObjectArrayElement(pParts, pidx++, env->NewStringUTF(filep->name));
-
+ jstring filename = env->NewStringUTF(filep->name);
+ CHECK_EXCEPTION_RETURN_VALUE(filename, false);
+ env->SetObjectArrayElement(pParts, pidx++, filename);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, false);
jobject pDataBuf = null;
- if (filep->data[0].len > 0)
+ if (filep->data[0].len > 0) {
pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr,
filep->data[0].len);
+ CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false);
+ }
env->SetObjectArrayElement(pParts, pidx++, pDataBuf);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, false);
pDataBuf = null;
- if (filep->data[1].len > 0)
+ if (filep->data[1].len > 0) {
pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr,
filep->data[1].len);
+ CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false);
+ }
env->SetObjectArrayElement(pParts, pidx++, pDataBuf);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, false);
return true;
}
JNIEXPORT jobject JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) {
unpacker* uPtr = get_unpacker(env, pObj);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL);
unpacker::file* filep = &uPtr->cur_file;
if (uPtr->aborting()) {
THROW_IOE(uPtr->get_abort_message());
- return false;
+ return null;
}
// We have fetched all the files.
// Now swallow up any remaining input.
if (uPtr->input_remaining() == 0) {
@@ -264,22 +314,25 @@
}
JNIEXPORT jlong JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) {
unpacker* uPtr = get_unpacker(env, pObj, false);
- if (uPtr == null) return 0;
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, 0);
size_t consumed = uPtr->input_consumed();
free_unpacker(env, pObj, uPtr);
return consumed;
}
JNIEXPORT jboolean JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj,
jstring pProp, jstring pValue) {
unpacker* uPtr = get_unpacker(env, pObj);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, false);
const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE);
+ CHECK_EXCEPTION_RETURN_VALUE(prop, false);
const char* value = env->GetStringUTFChars(pValue, JNI_FALSE);
+ CHECK_EXCEPTION_RETURN_VALUE(value, false);
jboolean retval = uPtr->set_option(prop, value);
env->ReleaseStringUTFChars(pProp, prop);
env->ReleaseStringUTFChars(pValue, value);
return retval;
}
@@ -287,11 +340,13 @@
JNIEXPORT jstring JNICALL
Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj,
jstring pProp) {
unpacker* uPtr = get_unpacker(env, pObj);
+ CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL);
const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE);
+ CHECK_EXCEPTION_RETURN_VALUE(prop, NULL);
const char* value = uPtr->get_option(prop);
+ CHECK_EXCEPTION_RETURN_VALUE(value, NULL);
env->ReleaseStringUTFChars(pProp, prop);
- if (value == null) return null;
return env->NewStringUTF(value);
}
< prev index next >