30
30
#include "dispatch.h"
31
31
32
32
#include <string.h>
33
+ #include <stdlib.h>
33
34
34
35
#if defined(_WIN32 )
35
36
#define WIN32_LEAN_AND_MEAN
53
54
#define DEFAULT_LOAD_OPTS LOAD_WITH_ALTERED_SEARCH_PATH
54
55
#endif
55
56
#define LOAD_LIBRARY (NAME ,OPTS ) (NAME ? LoadLibraryExW(NAME, NULL, OPTS) : GetModuleHandleW(NULL))
56
- #define LOAD_ERROR (BUF , LEN ) w32_format_error(GetLastError(), BUF, LEN )
57
- #define STR_ERROR (CODE , BUF , LEN ) w32_format_error(CODE, BUF, LEN )
57
+ #define LOAD_ERROR () w32_format_error(GetLastError())
58
+ #define STR_ERROR (CODE ) w32_format_error(CODE)
58
59
#define FREE_LIBRARY (HANDLE ) (((HANDLE)==GetModuleHandleW(NULL) || FreeLibrary(HANDLE))?0:-1)
59
60
#define FIND_ENTRY (HANDLE , NAME ) w32_find_entry(env, HANDLE, NAME)
60
61
#else
69
70
#endif
70
71
#define DEFAULT_LOAD_OPTS (RTLD_LAZY|RTLD_GLOBAL)
71
72
#define LOAD_LIBRARY (NAME ,OPTS ) dlopen(NAME, OPTS)
72
- static inline char * LOAD_ERROR (char * buf , size_t len ) {
73
- const size_t count = snprintf (buf , len , "%s" , dlerror ());
74
- assert (count <= len && "snprintf() output has been truncated" );
73
+ static inline char * LOAD_ERROR () {
74
+ char * message = dlerror ();
75
+ char * buf = (char * ) malloc (strlen (message ) + 1 /* null */ );
76
+ strcpy (buf , message );
75
77
return buf ;
76
78
}
77
- static inline char * STR_ERROR (int code , char * buf , size_t len ) {
78
- // The conversion will fail if code is not a valid error code.
79
- int err = strerror_r (code , buf , len );
80
- if (err )
81
- // Depending on glib version, "Unknown error" error code
82
- // may be returned or passed using errno.
83
- err = strerror_r (err > 0 ? err : errno , buf , len );
84
- assert (err == 0 && "strerror_r() conversion has failed" );
79
+ static inline char * STR_ERROR (int code ) {
80
+ int i ;
81
+ char * buf = NULL ;
82
+ for (i = 256 ; i < (10 * 1024 ); i += 256 ) {
83
+ buf = (char * ) malloc (i );
84
+ int res = strerror_r (code , buf , i );
85
+ if (res == 0 ) {
86
+ break ;
87
+ }
88
+ free (buf );
89
+ buf = NULL ;
90
+ if (res != ERANGE ) {
91
+ break ;
92
+ }
93
+ }
94
+ if (buf == NULL ) {
95
+ int requiredBuffer = 25 /* static part*/ + 10 /* space for int */ + 1 /* null */ ;
96
+ buf = (char * ) malloc (requiredBuffer );
97
+ snprintf (buf , requiredBuffer , "Failed to convert error: %d" , code );
98
+ }
85
99
return buf ;
86
100
}
87
101
#define FREE_LIBRARY (HANDLE ) dlclose(HANDLE)
@@ -263,26 +277,23 @@ typedef void (JNICALL* release_t)(JNIEnv*,jarray,void*,jint);
263
277
264
278
#ifdef _WIN32
265
279
static char *
266
- w32_format_error (int err , char * buf , int len ) {
280
+ w32_format_error (int err ) {
267
281
wchar_t * wbuf = NULL ;
282
+ char * buf = NULL ;
268
283
int wlen =
269
284
FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM
270
285
|FORMAT_MESSAGE_IGNORE_INSERTS
271
286
|FORMAT_MESSAGE_ALLOCATE_BUFFER ,
272
287
NULL , err , 0 , (LPWSTR )& wbuf , 0 , NULL );
273
288
if (wlen > 0 ) {
274
- int result = WideCharToMultiByte (CP_UTF8 , 0 , wbuf , -1 , buf , len , NULL , NULL );
289
+ int bufSize = WideCharToMultiByte (CP_UTF8 , 0 , wbuf , -1 , NULL , 0 , NULL , NULL );
290
+ buf = (char * )malloc (bufSize );
291
+ int result = WideCharToMultiByte (CP_UTF8 , 0 , wbuf , -1 , buf , bufSize , NULL , NULL );
275
292
if (result == 0 ) {
276
293
fprintf (stderr , "JNA: error converting error message: %d\n" , (int )GET_LAST_ERROR ());
277
- * buf = 0 ;
294
+ free (buf );
295
+ buf = NULL ;
278
296
}
279
- else {
280
- buf [len - 1 ] = 0 ;
281
- }
282
- }
283
- else {
284
- // Error retrieving message
285
- * buf = 0 ;
286
297
}
287
298
if (wbuf ) {
288
299
LocalFree (wbuf );
@@ -307,16 +318,18 @@ w32_short_name(JNIEnv* env, jstring str) {
307
318
wstr = wshort ;
308
319
}
309
320
else {
310
- char buf [MSG_SIZE ];
311
- throwByName (env , EError , LOAD_ERROR (buf , sizeof (buf )));
321
+ char * buf = LOAD_ERROR ();
322
+ throwByName (env , EError , buf );
323
+ free ((void * )buf );
312
324
free ((void * )wstr );
313
325
free ((void * )wshort );
314
326
wstr = NULL ;
315
327
}
316
328
}
317
329
else if (GET_LAST_ERROR () != ERROR_FILE_NOT_FOUND ) {
318
- char buf [MSG_SIZE ];
319
- throwByName (env , EError , LOAD_ERROR (buf , sizeof (buf )));
330
+ char * buf = LOAD_ERROR ();
331
+ throwByName (env , EError , buf );
332
+ free ((void * )buf );
320
333
free ((void * )wstr );
321
334
wstr = NULL ;
322
335
}
@@ -680,8 +693,9 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray args,
680
693
int err = GET_LAST_ERROR ();
681
694
JNA_set_last_error (env , err );
682
695
if ((flags & THROW_LAST_ERROR ) && err ) {
683
- char emsg [MSG_SIZE - 3 /* literal characters */ - 10 /* max length of %d */ ];
684
- snprintf (msg , sizeof (msg ), "[%d] %s" , err , STR_ERROR (err , emsg , sizeof (emsg )));
696
+ char * emsg = STR_ERROR (err );
697
+ snprintf (msg , MSG_SIZE , "[%d] %s" , err , emsg );
698
+ free (emsg );
685
699
throw_type = ELastError ;
686
700
throw_msg = msg ;
687
701
}
@@ -1926,8 +1940,9 @@ dispatch_direct(ffi_cif* cif, void* volatile resp, void** argp, void *cdata) {
1926
1940
int err = GET_LAST_ERROR ();
1927
1941
JNA_set_last_error (env , err );
1928
1942
if (data -> throw_last_error && err ) {
1929
- char emsg [MSG_SIZE - 3 /* literal characters */ - 10 /* max length of %d */ ];
1930
- snprintf (msg , sizeof (msg ), "[%d] %s" , err , STR_ERROR (err , emsg , sizeof (emsg )));
1943
+ char * emsg = STR_ERROR (err );
1944
+ snprintf (msg , sizeof (msg ), "[%d] %s" , err , emsg );
1945
+ free (emsg );
1931
1946
throw_type = ELastError ;
1932
1947
throw_msg = msg ;
1933
1948
}
@@ -2266,8 +2281,9 @@ Java_com_sun_jna_Native_open(JNIEnv *env, jclass UNUSED(cls), jstring lib, jint
2266
2281
}
2267
2282
#endif
2268
2283
if (!handle ) {
2269
- char buf [MSG_SIZE ];
2270
- throwByName (env , EUnsatisfiedLink , LOAD_ERROR (buf , sizeof (buf )));
2284
+ char * buf = LOAD_ERROR ();
2285
+ throwByName (env , EUnsatisfiedLink , buf );
2286
+ free (buf );
2271
2287
}
2272
2288
if (libname != NULL ) {
2273
2289
free ((void * )libname );
@@ -2284,8 +2300,9 @@ JNIEXPORT void JNICALL
2284
2300
Java_com_sun_jna_Native_close (JNIEnv * env , jclass UNUSED (cls ), jlong handle )
2285
2301
{
2286
2302
if (FREE_LIBRARY (L2A (handle ))) {
2287
- char buf [MSG_SIZE ];
2288
- throwByName (env , EError , LOAD_ERROR (buf , sizeof (buf )));
2303
+ char * buf = LOAD_ERROR ();
2304
+ throwByName (env , EError , buf );
2305
+ free (buf );
2289
2306
}
2290
2307
}
2291
2308
@@ -2305,8 +2322,9 @@ Java_com_sun_jna_Native_findSymbol(JNIEnv *env, jclass UNUSED(cls),
2305
2322
if (funname != NULL ) {
2306
2323
func = (void * )FIND_ENTRY (handle , funname );
2307
2324
if (!func ) {
2308
- char buf [MSG_SIZE ];
2309
- throwByName (env , EUnsatisfiedLink , LOAD_ERROR (buf , sizeof (buf )));
2325
+ char * buf = LOAD_ERROR ();
2326
+ throwByName (env , EUnsatisfiedLink , buf );
2327
+ free (buf );
2310
2328
}
2311
2329
free ((void * )funname );
2312
2330
}
@@ -3120,8 +3138,9 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv* UNUSED_JAWT(env), jclass UNUSED
3120
3138
free ((void * )prop );
3121
3139
}
3122
3140
if ((jawt_handle = LOAD_LIBRARY (path , DEFAULT_LOAD_OPTS )) == NULL ) {
3123
- char msg [MSG_SIZE ];
3124
- throwByName (env , EUnsatisfiedLink , LOAD_ERROR (msg , sizeof (msg )));
3141
+ char * msg = LOAD_ERROR ();
3142
+ throwByName (env , EUnsatisfiedLink , msg );
3143
+ free (msg );
3125
3144
return -1 ;
3126
3145
}
3127
3146
#else
@@ -3169,17 +3188,21 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv* UNUSED_JAWT(env), jclass UNUSED
3169
3188
3170
3189
if (jawt_handle == NULL ) {
3171
3190
if ((jawt_handle = LOAD_LIBRARY (jawtLibraryName , DEFAULT_LOAD_OPTS )) == NULL ) {
3172
- char msg [MSG_SIZE ];
3173
- throwByName (env , EUnsatisfiedLink , LOAD_ERROR (msg , sizeof (msg )));
3191
+ char * msg = LOAD_ERROR ();
3192
+ throwByName (env , EUnsatisfiedLink , msg );
3193
+ free (msg );
3174
3194
return -1 ;
3175
3195
}
3176
3196
}
3177
3197
#endif
3178
3198
if ((pJAWT_GetAWT = (void * )FIND_ENTRY (jawt_handle , METHOD_NAME )) == NULL ) {
3179
- char msg [MSG_SIZE ], buf [MSG_SIZE - 31 /* literal characters */ - sizeof (METHOD_NAME )];
3180
- snprintf (msg , sizeof (msg ), "Error looking up JAWT method %s: %s" ,
3181
- METHOD_NAME , LOAD_ERROR (buf , sizeof (buf )));
3199
+ char * buf = LOAD_ERROR ();
3200
+ size_t requiredBuffer = strlen (METHOD_NAME ) + strlen (buf ) + 31 /*static part*/ + 1 /*null*/ ;
3201
+ char * msg = (char * ) malloc (requiredBuffer );
3202
+ snprintf (msg , requiredBuffer , "Error looking up JAWT method %s: %s" , METHOD_NAME , buf );
3182
3203
throwByName (env , EUnsatisfiedLink , msg );
3204
+ free (buf );
3205
+ free (msg );
3183
3206
return -1 ;
3184
3207
}
3185
3208
}
0 commit comments