1
0
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:
Viktor Szakats
2023-03-07 14:06:35 +00:00
parent 730c606b64
commit 4cdf785cd3
13 changed files with 64 additions and 85 deletions

View File

@ -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

View File

@ -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__)

View File

@ -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

View File

@ -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";

View File

@ -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) >> $@

View File

@ -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/"

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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