From 266ab299cc7c780f62d2b8cd237200194c8ac465 Mon Sep 17 00:00:00 2001 From: Luca Longinotti Date: Thu, 13 Jun 2013 13:43:27 +0200 Subject: [PATCH] Wcast-qual was useuful to discover those errors in extra(): the returned ByteBuffer is fully writable, but the backing memory isn't really intended to be written to (and you never should modify the descriptors in memory). So fixed by getting a read-only ByteBuffer and passing that back to Java instead. --- src/main/c/src/ConfigDescriptor.c | 3 +-- src/main/c/src/EndpointDescriptor.c | 3 +-- src/main/c/src/InterfaceDescriptor.c | 2 +- src/main/c/src/usb4java.c | 18 +++++++++++++++++- src/main/c/src/usb4java.h | 2 ++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/c/src/ConfigDescriptor.c b/src/main/c/src/ConfigDescriptor.c index c95059f..f26c13c 100644 --- a/src/main/c/src/ConfigDescriptor.c +++ b/src/main/c/src/ConfigDescriptor.c @@ -162,8 +162,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(ConfigDescriptor, extra) struct libusb_config_descriptor *config = unwrapConfigDescriptor(env, this); if (!config) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) config->extra, - config->extra_length); + return NewDirectReadOnlyByteBuffer(env, config->extra, config->extra_length); } /** diff --git a/src/main/c/src/EndpointDescriptor.c b/src/main/c/src/EndpointDescriptor.c index 7e40a56..9d5973a 100644 --- a/src/main/c/src/EndpointDescriptor.c +++ b/src/main/c/src/EndpointDescriptor.c @@ -156,8 +156,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(EndpointDescriptor, extra) struct libusb_endpoint_descriptor *ep = unwrapEndpointDescriptor(env, this); if (!ep) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) ep->extra, - ep->extra_length); + return NewDirectReadOnlyByteBuffer(env, ep->extra, ep->extra_length); } /** diff --git a/src/main/c/src/InterfaceDescriptor.c b/src/main/c/src/InterfaceDescriptor.c index d2834d5..b3b722e 100644 --- a/src/main/c/src/InterfaceDescriptor.c +++ b/src/main/c/src/InterfaceDescriptor.c @@ -198,7 +198,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(InterfaceDescriptor, extra) unwrapInterfaceDescriptor(env, this); if (!interface) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) interface->extra, + return NewDirectReadOnlyByteBuffer(env, interface->extra, interface->extra_length); } diff --git a/src/main/c/src/usb4java.c b/src/main/c/src/usb4java.c index ebcd1cc..7a05959 100644 --- a/src/main/c/src/usb4java.c +++ b/src/main/c/src/usb4java.c @@ -19,7 +19,23 @@ jint illegalState(JNIEnv *env, const char *message) return (*env)->ThrowNew(env, cls, message); } -jint JNI_OnLoad(JavaVM *vm, void *reserved) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +jobject NewDirectReadOnlyByteBuffer(JNIEnv *env, const void *mem, + int mem_length) +{ + jobject buffer = (*env)->NewDirectByteBuffer(env, (void *) mem, mem_length); + + // Get a read-only buffer from this buffer. + jclass cls = (*env)->GetObjectClass(env, buffer); + jmethodID method = (*env)->GetMethodID(env, cls, "asReadOnlyBuffer", + "()Ljava/nio/ByteBuffer;"); + return (*env)->CallObjectMethod(env, buffer, method); +} +#pragma GCC diagnostic pop + +jint JNI_OnLoad(JavaVM *vm, void *reserved) +{ jvm = vm; return JNI_VERSION_1_4; } diff --git a/src/main/c/src/usb4java.h b/src/main/c/src/usb4java.h index 0ca325f..cee6e39 100644 --- a/src/main/c/src/usb4java.h +++ b/src/main/c/src/usb4java.h @@ -88,5 +88,7 @@ extern JavaVM *jvm; jint illegalArgument(JNIEnv *env, const char *message); jint illegalState(JNIEnv *env, const char *message); +jobject NewDirectReadOnlyByteBuffer(JNIEnv *env, const void *mem, + int mem_length); #endif