Skip to content

Commit

Permalink
Work for upstream PR 175.
Browse files Browse the repository at this point in the history
  • Loading branch information
hiddenalpha committed Nov 23, 2024
1 parent 187e460 commit 122f145
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 8 deletions.
8 changes: 7 additions & 1 deletion contrib/hiddenalpha-buildEnv-one/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Initially written for jssc 2.9.5.
-Wno-error=sign-compare \
-Wno-error=variadic-macros \
-Wno-long-long" \
&& PKGSTOADD="curl git g++ maven gdb patch zip unzip" \
&& PKGSTOADD="curl git g++ make cmake maven gdb patch zip unzip" \
&& SUDO=sudo \
&& JSSC_CPP=src/main/cpp/_nix_based/jssc.cpp \
&& LIBJSSC_SO=src/main/resources-precompiled/natives/linux_64/libjssc.so \
Expand Down Expand Up @@ -78,6 +78,12 @@ Initially written for jssc 2.9.5.
&& (cd target && sha256sum -b jssc-*.jar > "${SUMFILE:?}") \



## Use maven

&& mvn -Px86_64 ...


## gdb

For debugging, adjust CFLAGS to include debugger info and re-compile.
Expand Down
33 changes: 26 additions & 7 deletions src/main/cpp/windows/jssc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,17 +276,33 @@ JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes
HANDLE hComm = (HANDLE)portHandle;
DWORD lpNumberOfBytesTransferred;
DWORD lpNumberOfBytesRead;
jbyteArray returnArray = NULL;
jbyte *lpBuffer = NULL;
OVERLAPPED *overlapped = NULL;

jbyteArray returnArray = env->NewByteArray(byteCount);
if( byteCount < 0 ){
/* Negative byteCount makes no sense -> Report to caller by exception. */
char exMsg[48]; exMsg[0] = '\0';
snprintf(exMsg, sizeof exMsg, "byteCount %d", byteCount);
jclass exClz = env->FindClass("java/lang/IllegalArgumentException");
if( exClz != NULL ) env->ThrowNew(exClz, exMsg);
goto Finally;
}

returnArray = env->NewByteArray(byteCount);
if( returnArray == NULL ) goto Finally;

lpBuffer = (jbyte *)malloc(byteCount * sizeof(jbyte));
if(lpBuffer == NULL){
// return an empty array
return returnArray;
/* Whops. Not enough memory. Let caller know through exception. */
char exMsg[32]; exMsg[0] = '\0';
snprintf(exMsg, sizeof exMsg, "malloc(%d)", byteCount);
jclass exClz = env->FindClass("java/lang/OutOfMemoryError");
if( exClz != NULL ) env->ThrowNew(exClz, exMsg);
goto Finally;
}

OVERLAPPED *overlapped = new OVERLAPPED();
overlapped = new OVERLAPPED();
overlapped->hEvent = CreateEventA(NULL, true, false, NULL);
if(ReadFile(hComm, lpBuffer, (DWORD)byteCount, &lpNumberOfBytesRead, overlapped)){
env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer);
Expand All @@ -302,9 +318,12 @@ JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes
jclass exClz = env->FindClass("java/lang/IllegalArgumentException");
if( exClz != NULL ) env->ThrowNew(exClz, "EBADF");
}
CloseHandle(overlapped->hEvent);
delete overlapped;
free(lpBuffer);
Finally:
if( overlapped != NULL ){
CloseHandle(overlapped->hEvent);
delete overlapped;
}
if( lpBuffer != NULL ) free(lpBuffer);
return returnArray;
}

Expand Down
30 changes: 30 additions & 0 deletions src/test/java/jssc/SerialNativeInterfaceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,34 @@ public void throwsNpeIfPassedBufferIsNull() throws Exception {
new SerialNativeInterface().writeBytes(1, null);
}

@Test
public void throwsIaeIfCountNegative() throws Exception {
SerialNativeInterface testTarget = new SerialNativeInterface();
byte[] ret;
try{
ret = testTarget.readBytes(0, -42);
fail("Where's the exception?");
}catch( IllegalArgumentException ex ){
assertTrue(ex.getMessage().contains("-42"));
}
}

@Test
@org.junit.Ignore("This test only makes sense if it is run in a situation"
+" where large memory allocations WILL fail (for example you could use"
+" a virtual machine with low memory available). Because on regular"
+" machines allocating 2GiB of RAM is not a problem at all and so the"
+" test run will just happily wait infinitely for those 2GiB to arrive"
+" at the stdin fd. Feel free to remove this test if you think it"
+" doesn't make sense to have it here.")
public void throwsOOMExIfRequestTooLarge() throws Exception {
SerialNativeInterface testTarget = new SerialNativeInterface();
try{
byte[] ret = testTarget.readBytes(0, Integer.MAX_VALUE);
fail("Where's the exception?");
}catch( OutOfMemoryError ex ){
assertTrue(ex.getMessage().contains(String.valueOf(Integer.MAX_VALUE)));
}
}

}

0 comments on commit 122f145

Please sign in to comment.