diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index 1fd9fac..54e022b 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -67,6 +67,7 @@ jmethodID g_bufferPositionMethodId = NULL; jmethodID g_bufferLimitMethodId = NULL; jmethodID g_bufferHasArrayMethodId = NULL; jmethodID g_bufferArrayMethodId = NULL; +jmethodID g_bufferArrayOffsetMethodId = NULL; jmethodID g_bufferSetPositionMethodId = NULL; jmethodID g_verifyCallbackMethodId = NULL; @@ -185,6 +186,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) return JNI_ERR; } + g_bufferArrayOffsetMethodId = (*env)->GetMethodID(env, byteBufferClass, + "arrayOffset", "()I"); + if (g_bufferArrayOffsetMethodId == NULL) { + return JNI_ERR; + } + g_bufferSetPositionMethodId = (*env)->GetMethodID(env, byteBufferClass, "position", "(I)Ljava/nio/Buffer;"); if (g_bufferSetPositionMethodId == NULL) { @@ -236,6 +243,7 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) g_bufferLimitMethodId = NULL; g_bufferHasArrayMethodId = NULL; g_bufferArrayMethodId = NULL; + g_bufferArrayOffsetMethodId = NULL; g_bufferSetPositionMethodId = NULL; g_verifyCallbackMethodId = NULL; } diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index a3631d4..32bcda0 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -1303,6 +1303,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write__JLjava_nio_ByteBuf int ret = BAD_FUNC_ARG; int maxInputSz; int inSz = length; + int arrayOffset = 0; byte* data = NULL; WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr; jbyteArray bufArr = NULL; @@ -1333,6 +1334,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write__JLjava_nio_ByteBuf return SSL_FAILURE; } + /* Honor arrayOffset() for sliced/duplicated array-backed + * ByteBuffers, where logical position 0 maps to backing + * array index arrayOffset() */ + arrayOffset = (int)(*jenv)->CallIntMethod(jenv, buf, + g_bufferArrayOffsetMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } + /* Get array elements */ data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL); if (data == NULL) { @@ -1356,8 +1366,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write__JLjava_nio_ByteBuf } } - ret = SSLWriteNonblockingWithSelectPoll(ssl, data + position, - (int)inSz, (int)timeout); + ret = SSLWriteNonblockingWithSelectPoll(ssl, + data + arrayOffset + position, (int)inSz, (int)timeout); /* release memory if using array mode */ if (hasArray) { @@ -1530,6 +1540,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff int size = 0; int maxOutputSz; int outSz = length; + int arrayOffset = 0; byte* data = NULL; WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr; jbyteArray bufArr = NULL; @@ -1560,6 +1571,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff return SSL_FAILURE; } + /* Honor arrayOffset() for sliced/duplicated array-backed + * ByteBuffers, where logical position 0 maps to backing + * array index arrayOffset() */ + arrayOffset = (int)(*jenv)->CallIntMethod(jenv, buf, + g_bufferArrayOffsetMethodId); + if ((*jenv)->ExceptionCheck(jenv)) { + return SSL_FAILURE; + } + /* Get array elements */ data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL); if (data == NULL) { @@ -1583,8 +1603,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff } } - size = SSLReadNonblockingWithSelectPoll(ssl, data + position, - outSz, (int)timeout); + size = SSLReadNonblockingWithSelectPoll(ssl, + data + arrayOffset + position, outSz, (int)timeout); /* Release array elements if using array-backed buffer. * Note: DirectByteBuffer doesn't need releasing data */ diff --git a/native/com_wolfssl_globals.h b/native/com_wolfssl_globals.h index a353d9a..2fd20f1 100644 --- a/native/com_wolfssl_globals.h +++ b/native/com_wolfssl_globals.h @@ -42,6 +42,7 @@ extern jmethodID g_bufferPositionMethodId; /* ByteBuffer.position() */ extern jmethodID g_bufferLimitMethodId; /* ByteBuffer.limit() */ extern jmethodID g_bufferHasArrayMethodId; /* ByteBuffer.hasArray() */ extern jmethodID g_bufferArrayMethodId; /* ByteBuffer.array() */ +extern jmethodID g_bufferArrayOffsetMethodId; /* ByteBuffer.arrayOffset() */ extern jmethodID g_bufferSetPositionMethodId; /* ByteBuffer.position(int) */ extern jmethodID g_verifyCallbackMethodId; /* WolfSSLVerifyCallback.verifyCallback */