mirror of
https://github.com/libssh2/libssh2.git
synced 2025-07-31 00:03:08 +03:00
snprintf: unify fallback logic
Before this patch, the `snprintf()` fallback logic for envs not supporting this function (i.e. Visual Studio 2013 and older) varied depending on build tool, and used different techniques in examples, tests and libssh2 itself. This patch aims to apply a common logic to libssh2 and examples/tests. - libssh2: use local `snprintf()` fallback with all build tools. We already had a local implementation, but only with CMake. Move that to the library as `_libssh2_snprintf()`, and map `snprintf()` to it when `HAVE_SNPRINTF` is not set. Also change the length type from `int` to `size_t`, and fix formatting. - set or detect `HAVE_SNPRINTF` in non-CMake builds. Detect in autotools. Keep existing logic in `win32/libssh2_config.h`. Always set for OS/400, NetWare and VMS, keeping existing behaviour. (OS/400 builds use a different local implementation) - examples/tests: drop the CMake-specific fallback logic and map `snprintf()` to `_snprintf()` for old MSVC versions, like we did before with other build tools. This is unsafe, but should be fine for these uses. - `win32/libssh2_config.h`: make it easier to read. Closes #812
This commit is contained in:
@ -341,7 +341,7 @@ case $host in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_FUNCS(gettimeofday select strtoll memset_s)
|
||||
AC_CHECK_FUNCS(gettimeofday select strtoll memset_s snprintf)
|
||||
|
||||
dnl Check for select() into ws2_32 for Msys/Mingw
|
||||
if test "$ac_cv_func_select" != "yes"; then
|
||||
|
@ -90,8 +90,6 @@ check_include_files(winsock2.h HAVE_WINSOCK2_H)
|
||||
|
||||
check_symbol_exists(strcasecmp strings.h HAVE_STRCASECMP)
|
||||
check_symbol_exists(_stricmp string.h HAVE__STRICMP)
|
||||
check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF)
|
||||
check_symbol_exists(_snprintf stdio.h HAVE__SNPRINTF)
|
||||
|
||||
check_symbol_exists(__func__ "" HAVE___FUNC__)
|
||||
check_symbol_exists(__FUNCTION__ "" HAVE___FUNCTION__)
|
||||
|
@ -48,8 +48,6 @@
|
||||
/* Functions */
|
||||
#cmakedefine HAVE_STRCASECMP
|
||||
#cmakedefine HAVE__STRICMP
|
||||
#cmakedefine HAVE_SNPRINTF
|
||||
#cmakedefine HAVE__SNPRINTF
|
||||
|
||||
/* Workaround for platforms without POSIX strcasecmp (e.g. Windows) */
|
||||
#ifndef HAVE_STRCASECMP
|
||||
|
@ -37,10 +37,8 @@
|
||||
#define INADDR_NONE (in_addr_t)~0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# ifdef HAVE__SNPRINTF
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
const char *keyfile1 = "/home/username/.ssh/id_rsa.pub";
|
||||
|
@ -424,6 +424,7 @@ ifdef ENABLE_IPV6
|
||||
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
@echo $(DL)#define HAVE_SNPRINTF 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@
|
||||
|
@ -212,6 +212,10 @@
|
||||
/* Use OS/400 Qc3 */
|
||||
#define LIBSSH2_OS400QC3
|
||||
|
||||
/* Use our platform-specific local implementation:
|
||||
_libssh2_os400_snprintf */
|
||||
#define HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
@ -76,29 +76,3 @@
|
||||
#cmakedefine HAVE_IOCTLSOCKET_CASE
|
||||
#cmakedefine HAVE_SO_NONBLOCK
|
||||
#cmakedefine HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
|
||||
We provide a safe wrapper if snprintf not found */
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
|
||||
* then assume cp is pointing to a null char and do nothing. Returns number
|
||||
* number of chars placed in cp excluding the trailing null char. So for
|
||||
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
|
||||
* <= 0 the return value is 0 (and no chars are written to cp). */
|
||||
static int snprintf(char * cp, int cp_max_len, const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int n;
|
||||
|
||||
if (cp_max_len < 2)
|
||||
return 0;
|
||||
va_start(args, fmt);
|
||||
n = vsnprintf(cp, cp_max_len, fmt, args);
|
||||
va_end(args);
|
||||
return (n < cp_max_len) ? n : (cp_max_len - 1);
|
||||
}
|
||||
|
||||
#define HAVE_SNPRINTF
|
||||
#endif
|
||||
|
@ -126,6 +126,12 @@
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/* Use local implementation when not available */
|
||||
#if !defined(HAVE_SNPRINTF)
|
||||
#define LIBSSH2_SNPRINTF
|
||||
#define snprintf _libssh2_snprintf
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* "inline" keyword is valid only with C++ engine! */
|
||||
#define inline __inline
|
||||
|
24
src/misc.c
24
src/misc.c
@ -60,6 +60,30 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
|
||||
We provide a safe wrapper if snprintf not found */
|
||||
#ifdef LIBSSH2_SNPRINTF
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
|
||||
* then assume cp is pointing to a null char and do nothing. Returns number
|
||||
* number of chars placed in cp excluding the trailing null char. So for
|
||||
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
|
||||
* <= 0 the return value is 0 (and no chars are written to cp). */
|
||||
int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int n;
|
||||
|
||||
if(cp_max_len < 2)
|
||||
return 0;
|
||||
va_start(args, fmt);
|
||||
n = vsnprintf(cp, cp_max_len, fmt, args);
|
||||
va_end(args);
|
||||
return (n < cp_max_len) ? n : (cp_max_len - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
|
||||
const char *errmsg, int errflags)
|
||||
{
|
||||
|
@ -42,30 +42,3 @@
|
||||
#cmakedefine HAVE_ARPA_INET_H
|
||||
#cmakedefine HAVE_NETINET_IN_H
|
||||
#cmakedefine HAVE_WINSOCK2_H
|
||||
#cmakedefine HAVE_SNPRINTF
|
||||
|
||||
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
|
||||
We provide a safe wrapper if snprintf not found */
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
|
||||
* then assume cp is pointing to a null char and do nothing. Returns number
|
||||
* number of chars placed in cp excluding the trailing null char. So for
|
||||
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
|
||||
* <= 0 the return value is 0 (and no chars are written to cp). */
|
||||
static int snprintf(char *cp, int cp_max_len, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int n;
|
||||
|
||||
if (cp_max_len < 2)
|
||||
return 0;
|
||||
va_start(args, fmt);
|
||||
n = vsnprintf(cp, cp_max_len, fmt, args);
|
||||
va_end(args);
|
||||
return (n < cp_max_len) ? n : (cp_max_len - 1);
|
||||
}
|
||||
|
||||
#define HAVE_SNPRINTF
|
||||
#endif
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
#include <libssh2.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
LIBSSH2_SESSION *start_session_fixture(void);
|
||||
void stop_session_fixture(void);
|
||||
void print_last_session_error(const char *function);
|
||||
|
@ -25,6 +25,7 @@ typedef unsigned int socklen_t; /* missing in headers on VMS */
|
||||
#define HAVE_ARPA_INET_H
|
||||
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_SNPRINTF 1
|
||||
|
||||
#define POSIX_C_SOURCE
|
||||
|
||||
|
@ -4,38 +4,36 @@
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
#endif
|
||||
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif /* _CRT_SECURE_NO_DEPRECATE */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define HAVE_UNISTD_H
|
||||
#define HAVE_INTTYPES_H
|
||||
#define HAVE_SYS_TIME_H
|
||||
#define HAVE_GETTIMEOFDAY
|
||||
#endif /* __MINGW32__ */
|
||||
#endif
|
||||
|
||||
#define HAVE_LIBCRYPT32
|
||||
#define HAVE_WINSOCK2_H
|
||||
#define HAVE_IOCTLSOCKET
|
||||
#define HAVE_SELECT
|
||||
#define HAVE_SNPRINTF
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#if _MSC_VER < 1500
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strdup _strdup
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
#ifdef __MINGW32__
|
||||
# define HAVE_UNISTD_H
|
||||
# define HAVE_INTTYPES_H
|
||||
# define HAVE_SYS_TIME_H
|
||||
# define HAVE_GETTIMEOFDAY
|
||||
#elif defined(_MSC_VER)
|
||||
# if _MSC_VER < 1900
|
||||
# undef HAVE_SNPRINTF
|
||||
# if _MSC_VER < 1500
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# define strdup _strdup
|
||||
# define strncasecmp _strnicmp
|
||||
# define strcasecmp _stricmp
|
||||
# endif
|
||||
#else
|
||||
#ifndef __MINGW32__
|
||||
#define strncasecmp strnicmp
|
||||
#define strcasecmp stricmp
|
||||
#endif /* __MINGW32__ */
|
||||
#endif /* _MSC_VER */
|
||||
# define strncasecmp strnicmp
|
||||
# define strcasecmp stricmp
|
||||
#endif
|
||||
|
||||
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
|
||||
#define LIBSSH2_DH_GEX_NEW 1
|
||||
|
Reference in New Issue
Block a user