Merge pull request #250 from gasbytes/SSLEngine-patch
fix: handle DirectByteBuffers in WolfSSLSession.read()pull/249/head
commit
e600b0f056
|
@ -1215,75 +1215,82 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ByteBuffer.hasArray() does not throw any exceptions */
|
|
||||||
hasArray = (*jenv)->CallBooleanMethod(jenv, buf, hasArrayMeth);
|
|
||||||
if (!hasArray) {
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"ByteBuffer.hasArray() is false in native read()");
|
|
||||||
return BAD_FUNC_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only read up to maximum space we have in this ByteBuffer */
|
/* Only read up to maximum space we have in this ByteBuffer */
|
||||||
maxOutputSz = (limit - position);
|
maxOutputSz = (limit - position);
|
||||||
if (outSz > maxOutputSz) {
|
if (outSz > maxOutputSz) {
|
||||||
outSz = maxOutputSz;
|
outSz = maxOutputSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get reference to underlying byte[] from ByteBuffer */
|
hasArray = (*jenv)->CallBooleanMethod(jenv, buf, hasArrayMeth);
|
||||||
arrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "array", "()[B");
|
|
||||||
if (arrayMeth == NULL) {
|
if (hasArray) {
|
||||||
|
/* Get reference to underlying byte[] from ByteBuffer */
|
||||||
|
arrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "array", "()[B");
|
||||||
|
if (arrayMeth == NULL) {
|
||||||
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
}
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Failed to find ByteBuffer array() method in native read()");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf, arrayMeth);
|
||||||
|
|
||||||
|
/* Get array elements */
|
||||||
|
data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL);
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
(*jenv)->ExceptionClear(jenv);
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Exception when calling ByteBuffer.array() in native read()");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer array() method in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf, arrayMeth);
|
else {
|
||||||
|
data = (byte *)(*jenv)->GetDirectBufferAddress(jenv, buf);
|
||||||
/* Get array elements */
|
if (data == NULL) {
|
||||||
data = (byte*)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL);
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
"Failed to get DirectBuffer address in native read()");
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
return BAD_FUNC_ARG;
|
||||||
(*jenv)->ExceptionClear(jenv);
|
}
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Exception when calling ByteBuffer.array() in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
size = SSLReadNonblockingWithSelectPoll(ssl, data + position,
|
size = SSLReadNonblockingWithSelectPoll(ssl, data + position,
|
||||||
maxOutputSz, (int)timeout);
|
maxOutputSz, (int)timeout);
|
||||||
|
|
||||||
/* Relase array elements */
|
/* Relase array elements */
|
||||||
if (size < 0) {
|
if (hasArray) {
|
||||||
(*jenv)->ReleaseByteArrayElements(jenv, bufArr, (jbyte*)data,
|
if (size < 0) {
|
||||||
JNI_ABORT);
|
(*jenv)->ReleaseByteArrayElements(jenv, bufArr, (jbyte *)data,
|
||||||
}
|
JNI_ABORT);
|
||||||
else {
|
|
||||||
/* JNI_COMMIT commits the data but does not free the local array
|
|
||||||
* 0 is used here to both commit and free */
|
|
||||||
(*jenv)->ReleaseByteArrayElements(jenv, bufArr,
|
|
||||||
(jbyte*)data, 0);
|
|
||||||
|
|
||||||
/* Update ByteBuffer position() based on bytes written */
|
|
||||||
setPositionMeth = (*jenv)->GetMethodID(jenv, buffClass,
|
|
||||||
"position", "(I)Ljava/nio/Buffer;");
|
|
||||||
if (setPositionMeth == NULL) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to set ByteBuffer position() from "
|
|
||||||
"native read()");
|
|
||||||
size = -1;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(*jenv)->CallVoidMethod(jenv, buf, setPositionMeth,
|
(*jenv)->ReleaseByteArrayElements(jenv, bufArr,
|
||||||
position + size);
|
(jbyte *)data, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: DirectByteBuffer doesn't need releasing data */
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
/* Update ByteBuffer position() based on bytes written */
|
||||||
|
setPositionMeth = (*jenv)->GetMethodID(jenv, buffClass,
|
||||||
|
"position", "(I)Ljava/nio/Buffer;");
|
||||||
|
if (setPositionMeth == NULL) {
|
||||||
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
}
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Failed to set ByteBuffer position() from "
|
||||||
|
"native read()");
|
||||||
|
size = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*jenv)->CallVoidMethod(jenv, buf, setPositionMeth,
|
||||||
|
position + size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue