Merge pull request #250 from gasbytes/SSLEngine-patch

fix: handle DirectByteBuffers in WolfSSLSession.read()
pull/249/head
Chris Conlon 2025-01-10 11:50:30 -07:00 committed by GitHub
commit e600b0f056
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 57 additions and 50 deletions

View File

@ -1215,20 +1215,15 @@ 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;
} }
hasArray = (*jenv)->CallBooleanMethod(jenv, buf, hasArrayMeth);
if (hasArray) {
/* Get reference to underlying byte[] from ByteBuffer */ /* Get reference to underlying byte[] from ByteBuffer */
arrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "array", "()[B"); arrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "array", "()[B");
if (arrayMeth == NULL) { if (arrayMeth == NULL) {
@ -1251,23 +1246,35 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
"Exception when calling ByteBuffer.array() in native read()"); "Exception when calling ByteBuffer.array() in native read()");
return -1; return -1;
} }
}
else {
data = (byte *)(*jenv)->GetDirectBufferAddress(jenv, buf);
if (data == NULL) {
(*jenv)->ThrowNew(jenv, excClass,
"Failed to get DirectBuffer address in native read()");
return BAD_FUNC_ARG;
}
}
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 (hasArray) {
if (size < 0) { if (size < 0) {
(*jenv)->ReleaseByteArrayElements(jenv, bufArr, (jbyte *)data, (*jenv)->ReleaseByteArrayElements(jenv, bufArr, (jbyte *)data,
JNI_ABORT); JNI_ABORT);
} }
else { 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, (*jenv)->ReleaseByteArrayElements(jenv, bufArr,
(jbyte *)data, 0); (jbyte *)data, 0);
}
}
/* Note: DirectByteBuffer doesn't need releasing data */
if (size > 0) {
/* Update ByteBuffer position() based on bytes written */ /* Update ByteBuffer position() based on bytes written */
setPositionMeth = (*jenv)->GetMethodID(jenv, buffClass, setPositionMeth = (*jenv)->GetMethodID(jenv, buffClass,
"position", "(I)Ljava/nio/Buffer;"); "position", "(I)Ljava/nio/Buffer;");