From 40723e296b65d3ac89b457e1b7b27d17672aca50 Mon Sep 17 00:00:00 2001 From: David Keller Date: Fri, 10 Jun 2016 17:45:00 +0200 Subject: [PATCH 1/2] Ensure XSI-compliant strerror_r is used. This macro was used after some standard header includes. Depending on implementation, if one of theses headers were using , the later presence of _XOPEN_SOURCE macro would'nt matter. This prevents uninitialized buffer from being passed to snprintf. Signed-off-by: David Keller --- native/dispatch.c | 30 +++++++++++++++++++++--------- native/dispatch.h | 1 + 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/native/dispatch.c b/native/dispatch.c index 3712e12e87..735370a6bc 100644 --- a/native/dispatch.c +++ b/native/dispatch.c @@ -16,6 +16,10 @@ * Lesser General Public License for more details. */ +#include "dispatch.h" + +#include + #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include @@ -45,6 +49,7 @@ #else #include #include +#include #define STRTYPE char* #ifdef USE_DEFAULT_LIBNAME_ENCODING #define NAME2CSTR(ENV,JSTR) newCString(ENV,JSTR) @@ -53,8 +58,21 @@ #endif #define DEFAULT_LOAD_OPTS (RTLD_LAZY|RTLD_GLOBAL) #define LOAD_LIBRARY(NAME,OPTS) dlopen(NAME, OPTS) -#define LOAD_ERROR(BUF,LEN) (snprintf(BUF, LEN, "%s", dlerror()), BUF) -#define STR_ERROR(CODE,BUF,LEN) (strerror_r(CODE, BUF, LEN), BUF) +static inline char * LOAD_ERROR(char * buf, size_t len) { + const size_t count = snprintf(buf, len, "%s", dlerror()); + assert(count <= len && "snprintf() output has been truncated"); + return buf; +} +static inline char * STR_ERROR(int code, char * buf, size_t len) { + // The conversion will fail if code is not a valid error code. + int err = strerror_r(code, buf, len); + if (err) + // Depending on glib version, "Unknown error" error code + // may be returned or passed using errno. + err = strerror_r(err > 0 ? err : errno, buf, len); + assert(err == 0 && "strerror_r() conversion has failed"); + return buf; +} #define FREE_LIBRARY(HANDLE) dlclose(HANDLE) #define FIND_ENTRY(HANDLE, NAME) dlsym(HANDLE, NAME) #endif @@ -67,16 +85,10 @@ #endif #include -// Force XSI-compliant strerror_r (http://unixhelp.ed.ac.uk/CGI/man-cgi?strerror) -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 -#endif -#include +#include #include #include -#include "dispatch.h" - #ifndef NO_JAWT #include #include diff --git a/native/dispatch.h b/native/dispatch.h index 824c3ddd2b..9a5b9c003f 100644 --- a/native/dispatch.h +++ b/native/dispatch.h @@ -36,6 +36,7 @@ #define GET_LAST_ERROR() GetLastError() #define SET_LAST_ERROR(CODE) SetLastError(CODE) #else +#define _XOPEN_SOURCE 600 #define GET_LAST_ERROR() errno #define SET_LAST_ERROR(CODE) (errno = (CODE)) #endif /* _WIN32 */ From c74e73427aef8274e9bee3881986a04290254a45 Mon Sep 17 00:00:00 2001 From: David Keller Date: Sat, 17 Sep 2016 18:59:17 +0200 Subject: [PATCH 2/2] Fix header inclusion on Visual Studio/MinGW --- native/dispatch.c | 1 - native/dispatch.h | 2 +- native/protect.h | 1 + native/snprintf.h | 2 ++ 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/native/dispatch.c b/native/dispatch.c index 735370a6bc..900fe4a0f2 100644 --- a/native/dispatch.c +++ b/native/dispatch.c @@ -85,7 +85,6 @@ static inline char * STR_ERROR(int code, char * buf, size_t len) { #endif #include -#include #include #include diff --git a/native/dispatch.h b/native/dispatch.h index 9a5b9c003f..4e144cf083 100644 --- a/native/dispatch.h +++ b/native/dispatch.h @@ -18,7 +18,7 @@ #include "ffi.h" #include "com_sun_jna_Function.h" #include "com_sun_jna_Native.h" -#if defined(__sun__) || defined(_AIX) +#if defined(__sun__) || defined(_AIX) || defined(__linux__) # include #endif #ifdef _WIN32 diff --git a/native/protect.h b/native/protect.h index 21e29270e0..8e4ad64a90 100644 --- a/native/protect.h +++ b/native/protect.h @@ -44,6 +44,7 @@ #ifdef __GNUC__ #include #else +#include // copied from mingw header typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER) (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); diff --git a/native/snprintf.h b/native/snprintf.h index 2d94f7c916..9faaa7cc42 100644 --- a/native/snprintf.h +++ b/native/snprintf.h @@ -1,5 +1,6 @@ #ifndef _SNPRINTF_H #define _SNPRINTF_H +#if _MSC_VER < 1900 // Before Visual Studio 2015 // snprintf on windows is broken; always nul-terminate manually // DO NOT rely on the return value... static int snprintf(char * str, size_t size, const char * format, ...) { @@ -10,4 +11,5 @@ static int snprintf(char * str, size_t size, const char * format, ...) { va_end(ap); return retval; } +#endif #endif /* _SNPRINTF_H */