8193262: JNI array not released in libsunmscapi convertToLittleEndian
authorweijun
Thu, 08 Mar 2018 13:39:42 +0800
changeset 49151 a7d2f0dd9c1f
parent 49150 a4a816f88e58
child 49152 e38b6a7f65ee
8193262: JNI array not released in libsunmscapi convertToLittleEndian Reviewed-by: ascarpino
src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
--- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	Thu Mar 08 12:20:26 2018 +0800
+++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	Thu Mar 08 13:39:42 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1598,38 +1598,47 @@
  * Convert an array in big-endian byte order into little-endian byte order.
  */
 int convertToLittleEndian(JNIEnv *env, jbyteArray source, jbyte* destination,
-    int destinationLength) {
+        int destinationLength) {
+
+    int result = -1;
+    jbyte* sourceBytes = NULL;
 
-    int sourceLength = env->GetArrayLength(source);
+    __try {
+        int sourceLength = env->GetArrayLength(source);
+
+        sourceBytes = env->GetByteArrayElements(source, 0);
+        if (sourceBytes == NULL) {
+            __leave;
+        }
 
-    jbyte* sourceBytes = env->GetByteArrayElements(source, 0);
-    if (sourceBytes == NULL) {
-        return -1;
-    }
+        int copyLen = sourceLength;
+        if (sourceLength > destinationLength) {
+            // source might include an extra sign byte
+            if (sourceLength == destinationLength + 1 && sourceBytes[0] == 0) {
+                copyLen--;
+            } else {
+                __leave;
+            }
+        }
 
-    int copyLen = sourceLength;
-    if (sourceLength > destinationLength) {
-        // source might include an extra sign byte
-        if (sourceLength == destinationLength + 1 && sourceBytes[0] == 0) {
-            copyLen--;
-        } else {
-            return -1;
+        // Copy bytes from the end of the source array to the beginning of the
+        // destination array (until the destination array is full).
+        // This ensures that the sign byte from the source array will be excluded.
+        for (int i = 0; i < copyLen; i++) {
+            destination[i] = sourceBytes[sourceLength - 1 - i];
+        }
+        if (copyLen < destinationLength) {
+            memset(destination + copyLen, 0, destinationLength - copyLen);
+        }
+        result = destinationLength;
+    } __finally {
+        // Clean up.
+        if (sourceBytes) {
+            env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
         }
     }
 
-    // Copy bytes from the end of the source array to the beginning of the
-    // destination array (until the destination array is full).
-    // This ensures that the sign byte from the source array will be excluded.
-    for (int i = 0; i < copyLen; i++) {
-        destination[i] = sourceBytes[sourceLength - 1 - i];
-    }
-    if (copyLen < destinationLength) {
-        memset(destination + copyLen, 0, destinationLength - copyLen);
-    }
-
-    env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
-
-    return destinationLength;
+    return result;
 }
 
 /*