11/*
2- * Copyright (c) 2013, 2016 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2013, 2021 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -45,12 +45,21 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands
4545 return jmm_interface -> GetDiagnosticCommands (env );
4646}
4747
48- #define EXCEPTION_CHECK_AND_FREE (x ) do { \
49- if ((*env)->ExceptionCheck(env)) { \
50- free(x); \
51- return NULL; \
52- } \
53- } while(0)
48+ //
49+ // Checks for an exception and if one occurred,
50+ // pops 'pops' local frames and frees 'x' before
51+ // returning NULL
52+ //
53+ #define POP_EXCEPTION_CHECK_AND_FREE (pops , x ) do { \
54+ if ((*env)->ExceptionCheck(env)) { \
55+ int i; \
56+ for (i = 0; i < pops; i++) { \
57+ (*env)->PopLocalFrame(env, NULL); \
58+ } \
59+ free(x); \
60+ return NULL; \
61+ } \
62+ } while(0)
5463
5564jobject getDiagnosticCommandArgumentInfoArray (JNIEnv * env , jstring command ,
5665 int num_arg ) {
@@ -73,30 +82,29 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
7382 dcmd_arg_info_array );
7483 dcmdArgInfoCls = (* env )-> FindClass (env ,
7584 "com/sun/management/internal/DiagnosticCommandArgumentInfo" );
76- if ((* env )-> ExceptionCheck (env )) {
77- free (dcmd_arg_info_array );
78- return NULL ;
79- }
85+ POP_EXCEPTION_CHECK_AND_FREE (0 , dcmd_arg_info_array );
8086
8187 result = (* env )-> NewObjectArray (env , num_arg , dcmdArgInfoCls , NULL );
8288 if (result == NULL ) {
8389 free (dcmd_arg_info_array );
8490 return NULL ;
8591 }
8692 for (i = 0 ; i < num_arg ; i ++ ) {
87- jstring jname , jdesc ,jtype ,jdefStr ;
93+ // Capacity for 5 local refs: jname, jdesc, jtype, jdefStr and obj
94+ (* env )-> PushLocalFrame (env , 5 );
95+ jstring jname , jdesc , jtype , jdefStr ;
8896
8997 jname = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].name );
90- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
98+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
9199
92100 jdesc = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].description );
93- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
101+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
94102
95103 jtype = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].type );
96- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
104+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
97105
98106 jdefStr = (* env )-> NewStringUTF (env , dcmd_arg_info_array [i ].default_string );
99- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
107+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
100108 obj = JNU_NewObjectByName (env ,
101109 "com/sun/management/internal/DiagnosticCommandArgumentInfo" ,
102110 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V" ,
@@ -107,11 +115,13 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
107115 dcmd_arg_info_array [i ].multiple ,
108116 dcmd_arg_info_array [i ].position );
109117 if (obj == NULL ) {
118+ (* env )-> PopLocalFrame (env , NULL );
110119 free (dcmd_arg_info_array );
111120 return NULL ;
112121 }
122+ obj = (* env )-> PopLocalFrame (env , obj );
113123 (* env )-> SetObjectArrayElement (env , result , i , obj );
114- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
124+ POP_EXCEPTION_CHECK_AND_FREE ( 0 , dcmd_arg_info_array );
115125 }
116126 free (dcmd_arg_info_array );
117127 arraysCls = (* env )-> FindClass (env , "java/util/Arrays" );
@@ -144,51 +154,67 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
144154 jint ret = jmm_interface -> GetOptionalSupport (env , & mos );
145155 jsize num_commands ;
146156 dcmdInfo * dcmd_info_array ;
147- jstring jname , jdesc , jimpact ;
157+ jstring jname , jdesc , jimpact , cmd ;
148158
149159 if (commands == NULL ) {
150160 JNU_ThrowNullPointerException (env , "Invalid String Array" );
151161 return NULL ;
152162 }
153163 num_commands = (* env )-> GetArrayLength (env , commands );
164+ // Ensure capacity for 2 + num_commands local refs:
165+ // 2 => dcmdInfoCls, result
166+ // num_commmands => one obj per command
167+ (* env )-> PushLocalFrame (env , 2 + num_commands );
154168 dcmdInfoCls = (* env )-> FindClass (env ,
155169 "com/sun/management/internal/DiagnosticCommandInfo" );
156170 if ((* env )-> ExceptionCheck (env )) {
171+ (* env )-> PopLocalFrame (env , NULL );
157172 return NULL ;
158173 }
159174
160175 result = (* env )-> NewObjectArray (env , num_commands , dcmdInfoCls , NULL );
161176 if (result == NULL ) {
177+ (* env )-> PopLocalFrame (env , NULL );
162178 return NULL ;
163179 }
164180 if (num_commands == 0 ) {
181+ result = (* env )-> PopLocalFrame (env , result );
165182 /* Handle the 'zero commands' case specially to avoid calling 'malloc()' */
166183 /* with a zero argument because that may legally return a NULL pointer. */
167184 return result ;
168185 }
169186 dcmd_info_array = (dcmdInfo * ) malloc (num_commands * sizeof (dcmdInfo ));
170187 if (dcmd_info_array == NULL ) {
188+ (* env )-> PopLocalFrame (env , NULL );
171189 JNU_ThrowOutOfMemoryError (env , NULL );
172190 return NULL ;
173191 }
174192 jmm_interface -> GetDiagnosticCommandInfo (env , commands , dcmd_info_array );
175193 for (i = 0 ; i < num_commands ; i ++ ) {
194+ // Ensure capacity for 6 + 3 local refs:
195+ // 6 => jname, jdesc, jimpact, cmd, args, obj
196+ // 3 => permission class, name, action
197+ (* env )-> PushLocalFrame (env , 6 + 3 );
198+
199+ cmd = (* env )-> GetObjectArrayElement (env , commands , i );
176200 args = getDiagnosticCommandArgumentInfoArray (env ,
177- ( * env ) -> GetObjectArrayElement ( env , commands , i ) ,
201+ cmd ,
178202 dcmd_info_array [i ].num_arguments );
179203 if (args == NULL ) {
204+ (* env )-> PopLocalFrame (env , NULL );
205+ (* env )-> PopLocalFrame (env , NULL );
180206 free (dcmd_info_array );
181207 return NULL ;
182208 }
183209
184210 jname = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].name );
185- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
211+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
186212
187213 jdesc = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].description );
188- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
214+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
189215
190216 jimpact = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].impact );
191- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
217+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
192218
193219 obj = JNU_NewObjectByName (env ,
194220 "com/sun/management/internal/DiagnosticCommandInfo" ,
@@ -200,13 +226,17 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
200226 dcmd_info_array [i ].enabled ,
201227 args );
202228 if (obj == NULL ) {
229+ (* env )-> PopLocalFrame (env , NULL );
230+ (* env )-> PopLocalFrame (env , NULL );
203231 free (dcmd_info_array );
204232 return NULL ;
205233 }
234+ obj = (* env )-> PopLocalFrame (env , obj );
206235
207236 (* env )-> SetObjectArrayElement (env , result , i , obj );
208- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
237+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_info_array );
209238 }
239+ result = (* env )-> PopLocalFrame (env , result );
210240 free (dcmd_info_array );
211241 return result ;
212242}
0 commit comments