8043720: (smartcardio) Native memory should be handled more accurately
authorigerasim
Thu, 29 May 2014 10:17:08 +0400
changeset 24627 c2e7947c579e
parent 24626 87c5b99a6002
child 24628 a78064864267
8043720: (smartcardio) Native memory should be handled more accurately Reviewed-by: valeriep
jdk/src/share/native/sun/security/smartcardio/pcsc.c
--- a/jdk/src/share/native/sun/security/smartcardio/pcsc.c	Wed May 28 23:08:49 2014 -0700
+++ b/jdk/src/share/native/sun/security/smartcardio/pcsc.c	Thu May 29 10:17:08 2014 +0400
@@ -122,35 +122,28 @@
 /**
  * Convert a multi string to a java string array,
  */
-jobjectArray pcsc_multi2jstring(JNIEnv *env, char *spec) {
+jobjectArray pcsc_multi2jstring(JNIEnv *env, char *spec, DWORD size) {
     jobjectArray result;
     jclass stringClass;
-    char *cp, **tab;
+    char* tab[PCSCLITE_MAX_READERS_CONTEXTS];
     jstring js;
     int cnt = 0;
-
-    cp = spec;
-    while (*cp != 0) {
-        cp += (strlen(cp) + 1);
-        ++cnt;
-    }
+    DWORD i;
 
-    tab = (char **)malloc(cnt * sizeof(char *));
-    if (tab == NULL) {
-        throwOutOfMemoryError(env, NULL);
-        return NULL;
-    }
-
-    cnt = 0;
-    cp = spec;
-    while (*cp != 0) {
-        tab[cnt++] = cp;
-        cp += (strlen(cp) + 1);
+    if (spec && size) {
+        spec[size - 1] = 0;
+        for (i = 0; i < size && spec[i]; ++i) {
+            tab[cnt++] = spec + i;
+            if (cnt == PCSCLITE_MAX_READERS_CONTEXTS) {
+                break;
+            }
+            for (++i; i < size && spec[i]; ++i) {
+            }
+        }
     }
 
     stringClass = (*env)->FindClass(env, "java/lang/String");
     if (stringClass == NULL) {
-        free(tab);
         return NULL;
     }
 
@@ -159,18 +152,15 @@
         while (cnt-- > 0) {
             js = (*env)->NewStringUTF(env, tab[cnt]);
             if ((*env)->ExceptionCheck(env)) {
-                free(tab);
                 return NULL;
             }
             (*env)->SetObjectArrayElement(env, result, cnt, js);
             if ((*env)->ExceptionCheck(env)) {
-                free(tab);
                 return NULL;
             }
             (*env)->DeleteLocalRef(env, js);
         }
     }
-    free(tab);
     return result;
 }
 
@@ -179,7 +169,7 @@
 {
     SCARDCONTEXT context = (SCARDCONTEXT)jContext;
     LONG rv;
-    LPTSTR mszReaders;
+    LPTSTR mszReaders = NULL;
     DWORD size = 0;
     jobjectArray result;
 
@@ -190,20 +180,22 @@
     }
     dprintf1("-size: %d\n", size);
 
-    mszReaders = malloc(size);
-    if (mszReaders == NULL) {
-        throwOutOfMemoryError(env, NULL);
-        return NULL;
+    if (size) {
+        mszReaders = malloc(size);
+        if (mszReaders == NULL) {
+            throwOutOfMemoryError(env, NULL);
+            return NULL;
+        }
+
+        rv = CALL_SCardListReaders(context, NULL, mszReaders, &size);
+        if (handleRV(env, rv)) {
+            free(mszReaders);
+            return NULL;
+        }
+        dprintf1("-String: %s\n", mszReaders);
     }
 
-    rv = CALL_SCardListReaders(context, NULL, mszReaders, &size);
-    if (handleRV(env, rv)) {
-        free(mszReaders);
-        return NULL;
-    }
-    dprintf1("-String: %s\n", mszReaders);
-
-    result = pcsc_multi2jstring(env, mszReaders);
+    result = pcsc_multi2jstring(env, mszReaders, size);
     free(mszReaders);
     return result;
 }
@@ -336,7 +328,7 @@
     const char *readerName;
 
     readerState = calloc(readers, sizeof(SCARD_READERSTATE));
-    if (readerState == NULL) {
+    if (readerState == NULL && readers > 0) {
         throwOutOfMemoryError(env, NULL);
         return NULL;
     }
@@ -348,6 +340,10 @@
     }
 
     for (i = 0; i < readers; i++) {
+        readerState[i].szReader = NULL;
+    }
+
+    for (i = 0; i < readers; i++) {
         jobject jReaderName = (*env)->GetObjectArrayElement(env, jReaderNames, i);
         if ((*env)->ExceptionCheck(env)) {
             goto cleanup;
@@ -369,9 +365,11 @@
         (*env)->DeleteLocalRef(env, jReaderName);
     }
 
-    rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers);
-    if (handleRV(env, rv)) {
-        goto cleanup;
+    if (readers > 0) {
+        rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers);
+        if (handleRV(env, rv)) {
+            goto cleanup;
+        }
     }
 
     jEventState = (*env)->NewIntArray(env, readers);