From ec0feae7920d695ce234a5aba13014bf29824c09 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Thu, 13 Apr 2023 11:12:22 +0000 Subject: [PATCH] build: speed up and extend picky compiler options Implement picky warnings with clang in autotools. Extend picky gcc warnings, sync them between build tools and compilers and greatly speed up detection in CMake. - autotools: enable clang compiler warnings with `--enable-debug`. - autotools: enable more gcc compiler warnings with `--enable-debug`. - autotools/cmake: sync compiler warning options between gcc and clang. - sync compiler warning options between autotools and cmake. - cmake: reduce option-checks to speed up the detection phase. Bring them down to 3 (from 35). Leaving some checks to keep the CMake logic alive and for an easy way to add new options. clang 3.0 (2011-11-29) and gcc 2.95 (1999-07-31) now required. - autotools logic copied from curl, with these differences: - delete `-Wimplicit-fallthrough=4` due to a false positive. - reduce `-Wformat-truncation=2` to `1` due to a false positive. - simplify MinGW detection for `-Wno-pedantic-ms-format`. - cmake: show enabled picky compiler options (like autotools). - cmake: do compile `tests/simple.c` and `tests/ssh2.c`. - fix new compiler warnings. - `tests/CMakeLists.txt`: fix indentation. Original source of autotools logic: - https://github.com/curl/curl/blob/a8fbdb461cecbfe1ac6ecc5d8f6cf181e1507da8/acinclude.m4 - https://github.com/curl/curl/blob/a8fbdb461cecbfe1ac6ecc5d8f6cf181e1507da8/m4/curl-compilers.m4 Notice that the autotools implementation considers Apple clang as legacy clang 3.7. CMake detection works more accurately, at the same time more error-prone and difficult to update due to the sparsely documented nature of Apple clang option evolution. Closes #952 --- acinclude.m4 | 398 +++++++++++++++++- cmake/max_warnings.cmake | 170 +++++++- example/sftpdir_nonblock.c | 4 +- example/tcpip-forward.c | 6 +- example/x11.c | 4 +- src/agent.c | 28 +- src/agent.h | 6 +- src/comp.c | 2 +- src/hostkey.c | 4 +- src/kex.c | 211 +++++----- src/libgcrypt.h | 2 +- src/mbedtls.c | 21 +- src/openssl.c | 15 +- tests/CMakeLists.txt | 33 +- tests/openssh_fixture.c | 3 +- tests/session_fixture.c | 4 +- tests/simple.c | 4 +- tests/ssh2.c | 2 +- tests/test_agent_forward_succeeds.c | 6 +- ...t_keyboard_interactive_auth_info_request.c | 9 +- ...cceeds_with_correct_ed25519_key_from_mem.c | 4 +- 21 files changed, 740 insertions(+), 196 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 9c497944..9f60b9c1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,3 +1,145 @@ +dnl CURL_CPP_P +dnl +dnl Check if $cpp -P should be used for extract define values due to gcc 5 +dnl splitting up strings and defines between line outputs. gcc by default +dnl (without -P) will show TEST EINVAL TEST as +dnl +dnl # 13 "conftest.c" +dnl TEST +dnl # 13 "conftest.c" 3 4 +dnl 22 +dnl # 13 "conftest.c" +dnl TEST + +AC_DEFUN([CURL_CPP_P], [ + AC_MSG_CHECKING([if cpp -P is needed]) + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp=no], [cpp=yes]) + AC_MSG_RESULT([$cpp]) + + dnl we need cpp -P so check if it works then + if test "x$cpp" = "xyes"; then + AC_MSG_CHECKING([if cpp -P works]) + OLDCPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -P" + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp_p=yes], [cpp_p=no]) + AC_MSG_RESULT([$cpp_p]) + + if test "x$cpp_p" = "xno"; then + AC_MSG_WARN([failed to figure out cpp -P alternative]) + # without -P + CPPPFLAG="" + else + # with -P + CPPPFLAG="-P" + fi + dnl restore CPPFLAGS + CPPFLAGS=$OLDCPPFLAGS + else + # without -P + CPPPFLAG="" + fi +]) + +dnl CURL_CHECK_DEF (SYMBOL, [INCLUDES], [SILENT]) +dnl ------------------------------------------------- +dnl Use the C preprocessor to find out if the given object-style symbol +dnl is defined and get its expansion. This macro will not use default +dnl includes even if no INCLUDES argument is given. This macro will run +dnl silently when invoked with three arguments. If the expansion would +dnl result in a set of double-quoted strings the returned expansion will +dnl actually be a single double-quoted string concatenating all them. + +AC_DEFUN([CURL_CHECK_DEF], [ + AC_REQUIRE([CURL_CPP_P])dnl + OLDCPPFLAGS=$CPPFLAGS + # CPPPFLAG comes from CURL_CPP_P + CPPFLAGS="$CPPFLAGS $CPPPFLAG" + AS_VAR_PUSHDEF([ac_HaveDef], [curl_cv_have_def_$1])dnl + AS_VAR_PUSHDEF([ac_Def], [curl_cv_def_$1])dnl + if test -z "$SED"; then + AC_MSG_ERROR([SED not set. Cannot continue without SED being set.]) + fi + if test -z "$GREP"; then + AC_MSG_ERROR([GREP not set. Cannot continue without GREP being set.]) + fi + ifelse($3,,[AC_MSG_CHECKING([for preprocessor definition of $1])]) + tmp_exp="" + AC_PREPROC_IFELSE([ + AC_LANG_SOURCE( +ifelse($2,,,[$2])[[ +#ifdef $1 +CURL_DEF_TOKEN $1 +#endif + ]]) + ],[ + tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ + "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ + "$SED" 's/.*CURL_DEF_TOKEN[[ ]][[ ]]*//' 2>/dev/null | \ + "$SED" 's/[["]][[ ]]*[["]]//g' 2>/dev/null` + if test -z "$tmp_exp" || test "$tmp_exp" = "$1"; then + tmp_exp="" + fi + ]) + if test -z "$tmp_exp"; then + AS_VAR_SET(ac_HaveDef, no) + ifelse($3,,[AC_MSG_RESULT([no])]) + else + AS_VAR_SET(ac_HaveDef, yes) + AS_VAR_SET(ac_Def, $tmp_exp) + ifelse($3,,[AC_MSG_RESULT([$tmp_exp])]) + fi + AS_VAR_POPDEF([ac_Def])dnl + AS_VAR_POPDEF([ac_HaveDef])dnl + CPPFLAGS=$OLDCPPFLAGS +]) + +dnl CURL_CHECK_COMPILER_CLANG +dnl ------------------------------------------------- +dnl Verify if compiler being used is clang. + +AC_DEFUN([CURL_CHECK_COMPILER_CLANG], [ + AC_BEFORE([$0],[CURL_CHECK_COMPILER_GNU_C])dnl + AC_MSG_CHECKING([if compiler is clang]) + CURL_CHECK_DEF([__clang__], [], [silent]) + if test "$curl_cv_have_def___clang__" = "yes"; then + AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([if compiler is xlclang]) + CURL_CHECK_DEF([__ibmxl__], [], [silent]) + if test "$curl_cv_have_def___ibmxl__" = "yes" ; then + dnl IBM's almost-compatible clang version + AC_MSG_RESULT([yes]) + compiler_id="XLCLANG" + else + AC_MSG_RESULT([no]) + compiler_id="CLANG" + fi + fullclangver=`$CC -v 2>&1 | grep version` + clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` + if test -z "$clangver"; then + if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then + dnl Starting with XCode 7 / clang 3.7, Apple clang won't tell its upstream version + clangver="3.7" + else + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + fi + fi + clangvhi=`echo $clangver | cut -d . -f1` + clangvlo=`echo $clangver | cut -d . -f2` + compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + flags_dbg_yes="-g" + flags_opt_all="-O -O0 -O1 -O2 -Os -O3 -O4" + flags_opt_yes="-O2" + flags_opt_off="-O0" + else + AC_MSG_RESULT([no]) + fi +]) dnl ********************************************************************** dnl CURL_DETECT_ICC ([ACTION-IF-YES]) @@ -33,11 +175,123 @@ dnl options are only used for debug-builds. AC_DEFUN([CURL_CC_DEBUG_OPTS], [ + if test "z$CLANG" = "z"; then + CURL_CHECK_COMPILER_CLANG + if test "z$compiler_id" = "zCLANG"; then + CLANG="yes" + else + CLANG="no" + fi + fi if test "z$ICC" = "z"; then CURL_DETECT_ICC fi - if test "$GCC" = "yes"; then + if test "$CLANG" = "yes"; then + + dnl figure out clang version! + AC_MSG_CHECKING([clang version]) + fullclangver=`$CC -v 2>&1 | grep version` + clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` + if test -z "$clangver"; then + if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then + dnl Starting with Xcode 7 / clang 3.7, Apple clang won't tell its upstream version + clangver="3.7" + else + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + fi + fi + clangvhi=`echo $clangver | cut -d . -f1` + clangvlo=`echo $clangver | cut -d . -f2` + compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + AC_MSG_RESULT($compiler_num) + + WARN="-pedantic" + CURL_ADD_COMPILER_WARNINGS([WARN], [all extra]) + CURL_ADD_COMPILER_WARNINGS([WARN], [pointer-arith write-strings]) + CURL_ADD_COMPILER_WARNINGS([WARN], [shadow]) + CURL_ADD_COMPILER_WARNINGS([WARN], [inline nested-externs]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-declarations]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-prototypes]) + WARN="$WARN -Wno-long-long" + CURL_ADD_COMPILER_WARNINGS([WARN], [float-equal]) + CURL_ADD_COMPILER_WARNINGS([WARN], [no-multichar sign-compare]) + CURL_ADD_COMPILER_WARNINGS([WARN], [undef]) + WARN="$WARN -Wno-format-nonliteral" + CURL_ADD_COMPILER_WARNINGS([WARN], [endif-labels strict-prototypes]) + CURL_ADD_COMPILER_WARNINGS([WARN], [declaration-after-statement]) + CURL_ADD_COMPILER_WARNINGS([WARN], [cast-align]) + WARN="$WARN -Wno-system-headers" + CURL_ADD_COMPILER_WARNINGS([WARN], [shorten-64-to-32]) + # + dnl Only clang 1.1 or later + if test "$compiler_num" -ge "101"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [unused]) + fi + # + dnl Only clang 2.8 or later + if test "$compiler_num" -ge "208"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [vla]) + fi + # + dnl Only clang 2.9 or later + if test "$compiler_num" -ge "209"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [shift-sign-overflow]) + fi + # + dnl Only clang 3.0 or later (possibly earlier) + if test "$compiler_num" -ge "300"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [conversion]) + CURL_ADD_COMPILER_WARNINGS([WARN], [empty-body]) + CURL_ADD_COMPILER_WARNINGS([WARN], [ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([WARN], [type-limits]) + CURL_ADD_COMPILER_WARNINGS([WARN], [no-sign-conversion]) + fi + # + dnl Only clang 3.2 or later + if test "$compiler_num" -ge "302"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [enum-conversion]) + case $host_os in + cygwin* | mingw*) + dnl skip missing-variable-declarations warnings for cygwin and + dnl mingw because the libtool wrapper executable causes them + ;; + *) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-variable-declarations]) + ;; + esac + fi + # + dnl Only clang 3.4 or later + if test "$compiler_num" -ge "304"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [unused-const-variable]) + fi + # + dnl Only clang 3.6 or later + if test "$compiler_num" -ge "306"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [double-promotion]) + fi + # + dnl Only clang 3.9 or later + if test "$compiler_num" -ge "309"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [comma]) + # avoid the varargs warning, fixed in 4.0 + # https://bugs.llvm.org/show_bug.cgi?id=29140 + if test "$compiler_num" -lt "400"; then + WARN="$WARN -Wno-varargs" + fi + fi + dnl clang 7 or later + if test "$compiler_num" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [assign-enum]) + CURL_ADD_COMPILER_WARNINGS([WARN], [extra-semi-stmt]) + fi + + CFLAGS="$CFLAGS $WARN" + + AC_MSG_NOTICE([Added this set of compiler options: $WARN]) + + elif test "$GCC" = "yes"; then dnl figure out gcc version! AC_MSG_CHECKING([gcc version]) @@ -69,8 +323,6 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], dnl this is a set of options we believe *ALL* gcc versions support: WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes" - dnl -Wcast-align is a bit too annoying on all gcc versions ;-) - if test "$gccnum" -ge "207"; then dnl gcc 2.7 or later WARN="$WARN -Wmissing-declarations" @@ -80,7 +332,7 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], dnl only if the compiler is newer than 2.95 since we got lots of dnl "`_POSIX_C_SOURCE' is not defined" in system headers with dnl gcc 2.95.4 on FreeBSD 4.9! - WARN="$WARN -Wundef -Wno-long-long -Wsign-compare" + WARN="$WARN -Wundef -Wno-long-long -Wno-multichar -Wshadow -Wsign-compare -Wunused" fi if test "$gccnum" -ge "296"; then @@ -108,6 +360,83 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], WARN="$WARN -Wdeclaration-after-statement" fi + dnl Only gcc 4.0 or later + if test "$gccnum" -ge "400"; then + WARN="$WARN -Wstrict-aliasing=3" + fi + # + dnl Only gcc 4.1 or later (possibly earlier) + if test "$gccnum" -ge "401"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [no-system-headers]) + fi + # + dnl Only gcc 4.2 or later + if test "$gccnum" -ge "402"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [cast-align]) + fi + # + dnl Only gcc 4.3 or later + if test "$gccnum" -ge "403"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [type-limits old-style-declaration]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-parameter-type empty-body]) + CURL_ADD_COMPILER_WARNINGS([WARN], [ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([WARN], [conversion]) + WARN="$WARN -Wno-sign-conversion" + CURL_ADD_COMPILER_WARNINGS([WARN], [vla]) + dnl required for -Warray-bounds, included in -Wall + WARN="$WARN -ftree-vrp" + fi + # + dnl Only gcc 4.5 or later + if test "$gccnum" -ge "405"; then + dnl Only windows targets + case $host_os in + mingw*) + WARN="$WARN -Wno-pedantic-ms-format" + ;; + esac + fi + # + dnl Only gcc 4.6 or later + if test "$gccnum" -ge "406"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [double-promotion]) + fi + # + dnl only gcc 4.8 or later + if test "$gccnum" -ge "408"; then + WARN="$WARN -Wformat=2" + fi + # + dnl Only gcc 5 or later + if test "$gccnum" -ge "500"; then + WARN="$WARN -Warray-bounds=2" + fi + # + dnl Only gcc 6 or later + if test "$gccnum" -ge "600"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [shift-negative-value]) + WARN="$WARN -Wshift-overflow=2" + CURL_ADD_COMPILER_WARNINGS([WARN], [null-dereference]) + WARN="$WARN -fdelete-null-pointer-checks" + CURL_ADD_COMPILER_WARNINGS([WARN], [duplicated-cond]) + CURL_ADD_COMPILER_WARNINGS([WARN], [unused-const-variable]) + fi + # + dnl Only gcc 7 or later + if test "$gccnum" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [duplicated-branches]) + CURL_ADD_COMPILER_WARNINGS([WARN], [restrict]) + CURL_ADD_COMPILER_WARNINGS([WARN], [alloc-zero]) + WARN="$WARN -Wformat-overflow=2" + WARN="$WARN -Wformat-truncation=1" + fi + # + dnl Only gcc 10 or later + if test "$gccnum" -ge "1000"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [arith-conversion]) + CURL_ADD_COMPILER_WARNINGS([WARN], [enum-conversion]) + fi + for flag in $CPPFLAGS; do case "$flag" in -I*) @@ -148,6 +477,67 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], ]) dnl end of AC_DEFUN() +dnl CURL_ADD_COMPILER_WARNINGS (WARNING-LIST, NEW-WARNINGS) +dnl ------------------------------------------------------- +dnl Contents of variable WARNING-LIST and NEW-WARNINGS are +dnl handled as whitespace separated lists of words. +dnl Add each compiler warning from NEW-WARNINGS that has not +dnl been disabled via CFLAGS to WARNING-LIST. + +AC_DEFUN([CURL_ADD_COMPILER_WARNINGS], [ + AC_REQUIRE([CURL_SHFUNC_SQUEEZE])dnl + ac_var_added_warnings="" + for warning in [$2]; do + CURL_VAR_MATCH(CFLAGS, [-Wno-$warning -W$warning]) + if test "$ac_var_match_word" = "no"; then + ac_var_added_warnings="$ac_var_added_warnings -W$warning" + fi + done + dnl squeeze whitespace out of result + [$1]="$[$1] $ac_var_added_warnings" + squeeze [$1] +]) + +dnl CURL_SHFUNC_SQUEEZE +dnl ------------------------------------------------- +dnl Declares a shell function squeeze() which removes +dnl redundant whitespace out of a shell variable. + +AC_DEFUN([CURL_SHFUNC_SQUEEZE], [ +squeeze() { + _sqz_result="" + eval _sqz_input=\[$][$]1 + for _sqz_token in $_sqz_input; do + if test -z "$_sqz_result"; then + _sqz_result="$_sqz_token" + else + _sqz_result="$_sqz_result $_sqz_token" + fi + done + eval [$]1=\$_sqz_result + return 0 +} +]) + +dnl CURL_VAR_MATCH (VARNAME, VALUE) +dnl ------------------------------------------------- +dnl Verifies if shell variable VARNAME contains VALUE. +dnl Contents of variable VARNAME and VALUE are handled +dnl as whitespace separated lists of words. If at least +dnl one word of VALUE is present in VARNAME the match +dnl is considered positive, otherwise false. + +AC_DEFUN([CURL_VAR_MATCH], [ + ac_var_match_word="no" + for word1 in $[$1]; do + for word2 in [$2]; do + if test "$word1" = "$word2"; then + ac_var_match_word="yes" + fi + done + done +]) + dnl CURL_CHECK_NONBLOCKING_SOCKET dnl ------------------------------------------------- dnl Check for how to set a socket to non-blocking state. There seems to exist diff --git a/cmake/max_warnings.cmake b/cmake/max_warnings.cmake index 1f42b03c..dfa614ea 100644 --- a/cmake/max_warnings.cmake +++ b/cmake/max_warnings.cmake @@ -28,6 +28,10 @@ if(MSVC) endif() endif() elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang") + + # https://clang.llvm.org/docs/DiagnosticsReference.html + # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html + if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() @@ -36,23 +40,169 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_I endif() if(PICKY_COMPILER) - foreach(_CCOPT -pedantic -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wfloat-equal -Wsign-compare -Wundef -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wvla -Wdouble-promotion -Wenum-conversion -Warith-conversion) + + # WPICKY_ENABLE = Options we want to enable as-is. + # WPICKY_DETECT = Options we want to test first and enable if available. + + # Prefer the -Wextra alias with clang. + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(WPICKY_ENABLE "-Wextra") + else() + set(WPICKY_ENABLE "-W") + endif() + + list(APPEND WPICKY_ENABLE + -pedantic + ) + + # ---------------------------------- + # Add new options here, if in doubt: + # ---------------------------------- + set(WPICKY_DETECT + ) + + # Assume these options always exist with both clang and gcc. + # Require clang 3.0 / gcc 2.95 or later. + list(APPEND WPICKY_ENABLE + -Wconversion # clang 3.0 gcc 2.95 + -Winline # clang 1.0 gcc 1.0 + -Wmissing-declarations # clang 1.0 gcc 2.7 + -Wmissing-prototypes # clang 1.0 gcc 1.0 + -Wnested-externs # clang 1.0 gcc 1.0 + -Wno-long-long # clang 1.0 gcc 2.95 + -Wno-multichar # clang 1.0 gcc 2.95 + -Wpointer-arith # clang 1.0 gcc 1.0 + -Wshadow # clang 1.0 gcc 2.95 + -Wsign-compare # clang 1.0 gcc 2.95 + -Wundef # clang 1.0 gcc 2.95 + -Wunused # clang 1.1 gcc 2.95 + -Wwrite-strings # clang 1.0 gcc 1.0 + ) + + # Always enable with clang, version dependent with gcc + set(WPICKY_COMMON_OLD + -Wcast-align # clang 1.0 gcc 4.2 + -Wdeclaration-after-statement # clang 1.0 gcc 3.4 + -Wempty-body # clang 3.0 gcc 4.3 + -Wendif-labels # clang 1.0 gcc 3.3 + -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) + -Wignored-qualifiers # clang 3.0 gcc 4.3 + -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) + -Wno-sign-conversion # clang 3.0 gcc 4.3 + -Wno-system-headers # clang 1.0 gcc 3.0 + -Wstrict-prototypes # clang 1.0 gcc 3.3 + -Wtype-limits # clang 3.0 gcc 4.3 + -Wvla # clang 2.8 gcc 4.3 + ) + + set(WPICKY_COMMON + -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 + -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 + -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 + ) + + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON_OLD} + -Wshift-sign-overflow # clang 2.9 + -Wshorten-64-to-32 # clang 1.0 + ) + # Enable based on compiler version + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3)) + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON} + ) + endif() + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3)) + list(APPEND WPICKY_ENABLE + -Wcomma # clang 3.9 appleclang 8.3 + -Wmissing-variable-declarations # clang 3.2 appleclang 4.6 + ) + endif() + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3)) + list(APPEND WPICKY_ENABLE + -Wassign-enum # clang 7.0 appleclang 10.3 + -Wextra-semi-stmt # clang 7.0 appleclang 10.3 + ) + endif() + else() # gcc + list(APPEND WPICKY_DETECT + ${WPICKY_COMMON} + ) + # Enable based on compiler version + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3) + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON_OLD} + -Wmissing-parameter-type # gcc 4.3 + -Wold-style-declaration # gcc 4.3 + -Wstrict-aliasing=3 # gcc 4.0 + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW) + list(APPEND WPICKY_ENABLE + -Wno-pedantic-ms-format # gcc 4.5 (mingw-only) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) + list(APPEND WPICKY_ENABLE + -Wformat=2 # clang 3.0 gcc 4.8 (clang part-default, enabling it fully causes -Wformat-nonliteral warnings) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) + list(APPEND WPICKY_ENABLE + -Warray-bounds=2 -ftree-vrp # clang 3.0 gcc 5.0 (clang default: -Warray-bounds) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) + list(APPEND WPICKY_ENABLE + -Wduplicated-cond # gcc 6.0 + -Wnull-dereference # clang 3.0 gcc 6.0 (clang default) + -fdelete-null-pointer-checks + -Wshift-negative-value # clang 3.7 gcc 6.0 (clang default) + -Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) + list(APPEND WPICKY_ENABLE + -Walloc-zero # gcc 7.0 + -Wduplicated-branches # gcc 7.0 + -Wformat-overflow=2 # gcc 7.0 + -Wformat-truncation=1 # gcc 7.0 + -Wrestrict # gcc 7.0 + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) + list(APPEND WPICKY_ENABLE + -Warith-conversion # gcc 10.0 + ) + endif() + endif() + + # + + unset(WPICKY) + + foreach(_CCOPT ${WPICKY_ENABLE}) + set(WPICKY "${WPICKY} ${_CCOPT}") + endforeach() + + foreach(_CCOPT ${WPICKY_DETECT}) # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new # test result in. string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname) - check_c_compiler_flag(${_CCOPT} ${_optvarname}) - if(${_optvarname}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}") - endif() - endforeach() - foreach(_CCOPT long-long multichar format-nonliteral sign-conversion system-headers pedantic-ms-format) # GCC only warns about unknown -Wno- options if there are also other diagnostic messages, # so test for the positive form instead - string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname) - check_c_compiler_flag("-W${_CCOPT}" ${_optvarname}) + string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}") + check_c_compiler_flag(${_CCOPT_ON} ${_optvarname}) if(${_optvarname}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-${_CCOPT}") + set(WPICKY "${WPICKY} ${_CCOPT}") endif() endforeach() + + message(STATUS "Picky compiler options:${WPICKY}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WPICKY}") endif() endif() diff --git a/example/sftpdir_nonblock.c b/example/sftpdir_nonblock.c index cc8d888b..976dea47 100644 --- a/example/sftpdir_nonblock.c +++ b/example/sftpdir_nonblock.c @@ -185,9 +185,7 @@ int main(int argc, char *argv[]) /* loop until we fail */ while((rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem), - &attrs)) == LIBSSH2_ERROR_EAGAIN) { - ; - } + &attrs)) == LIBSSH2_ERROR_EAGAIN); if(rc > 0) { /* rc is the length of the file name in the mem buffer */ diff --git a/example/tcpip-forward.c b/example/tcpip-forward.c index d802c58e..7925a02b 100644 --- a/example/tcpip-forward.c +++ b/example/tcpip-forward.c @@ -46,11 +46,11 @@ static const char *server_ip = "127.0.0.1"; /* resolved by the server */ static const char *remote_listenhost = "localhost"; -int remote_wantport = 2222; -int remote_listenport; +static int remote_wantport = 2222; +static int remote_listenport; static const char *local_destip = "127.0.0.1"; -int local_destport = 22; +static int local_destport = 22; enum { AUTH_NONE = 0, diff --git a/example/x11.c b/example/x11.c index e5c6815c..4c0a1d4c 100644 --- a/example/x11.c +++ b/example/x11.c @@ -55,8 +55,8 @@ struct chan_X11_list { struct chan_X11_list *next; }; -struct chan_X11_list * gp_x11_chan = NULL; -struct termios _saved_tio; +static struct chan_X11_list * gp_x11_chan = NULL; +static struct termios _saved_tio; /* * Utility function to remove a Node of the chained list diff --git a/src/agent.c b/src/agent.c index a7b5de7e..9ac83bb2 100644 --- a/src/agent.c +++ b/src/agent.c @@ -128,20 +128,22 @@ agent_connect_unix(LIBSSH2_AGENT *agent) } #define RECV_SEND_ALL(func, socket, buffer, length, flags, abstract) \ - size_t finished = 0; \ + do { \ + size_t finished = 0; \ \ - while(finished < length) { \ - ssize_t rc; \ - rc = func(socket, \ - (char *)buffer + finished, length - finished, \ - flags, abstract); \ - if(rc < 0) \ - return rc; \ + while(finished < length) { \ + ssize_t rc; \ + rc = func(socket, \ + (char *)buffer + finished, length - finished, \ + flags, abstract); \ + if(rc < 0) \ + return rc; \ \ - finished += rc; \ - } \ + finished += rc; \ + } \ \ - return finished; + return finished; \ + } while(0) static ssize_t _send_all(LIBSSH2_SEND_FUNC(func), libssh2_socket_t socket, const void *buffer, size_t length, @@ -242,7 +244,7 @@ agent_disconnect_unix(LIBSSH2_AGENT *agent) return LIBSSH2_ERROR_NONE; } -struct agent_ops agent_ops_unix = { +static struct agent_ops agent_ops_unix = { agent_connect_unix, agent_transact_unix, agent_disconnect_unix @@ -347,7 +349,7 @@ agent_disconnect_pageant(LIBSSH2_AGENT *agent) return 0; } -struct agent_ops agent_ops_pageant = { +static struct agent_ops agent_ops_pageant = { agent_connect_pageant, agent_transact_pageant, agent_disconnect_pageant diff --git a/src/agent.h b/src/agent.h index 605ba05d..5c334e8a 100644 --- a/src/agent.h +++ b/src/agent.h @@ -75,9 +75,9 @@ struct agent_publickey { }; struct agent_ops { - agent_connect_func connect; - agent_transact_func transact; - agent_disconnect_func disconnect; + const agent_connect_func connect; + const agent_transact_func transact; + const agent_disconnect_func disconnect; }; struct _LIBSSH2_AGENT diff --git a/src/comp.c b/src/comp.c index 88445272..81ca89bf 100644 --- a/src/comp.c +++ b/src/comp.c @@ -237,7 +237,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session, /* If strm is null, then we have not yet been initialized. */ if(strm == NULL) return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, - "decompression uninitialized");; + "decompression uninitialized"); /* In practice they never come smaller than this */ if(out_maxlen < 25) diff --git a/src/hostkey.c b/src/hostkey.c index 0639d787..6553ab6f 100644 --- a/src/hostkey.c +++ b/src/hostkey.c @@ -894,7 +894,7 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session, #define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \ - { \ + do { \ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ libssh2_sha##digest_type##_ctx ctx; \ int i; \ @@ -907,7 +907,7 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session, ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \ SHA##digest_type##_DIGEST_LENGTH, \ signature, signature_len); \ - } + } while(0) /* diff --git a/src/kex.c b/src/kex.c index 83b522cb..b7a27645 100644 --- a/src/kex.c +++ b/src/kex.c @@ -54,7 +54,7 @@ kex_method_diffie_hellman_group1_sha1_key_exchange */ #define LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(value, reqlen, version) \ - { \ + do { \ if(type == LIBSSH2_EC_CURVE_NISTP256) { \ LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, value, reqlen, version); \ } \ @@ -64,12 +64,11 @@ else if(type == LIBSSH2_EC_CURVE_NISTP521) { \ LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, value, reqlen, version); \ } \ - } \ - + } while(0) #define LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(digest_type, value, \ reqlen, version) \ -{ \ +do { \ libssh2_sha##digest_type##_ctx hash; \ size_t len = 0; \ if(!(value)) { \ @@ -96,7 +95,7 @@ libssh2_sha##digest_type##_final(hash, (value) + len); \ len += SHA##digest_type##_DIGEST_LENGTH; \ } \ -} +} while(0) /*! * @note The following are wrapper functions used by diffie_hellman_sha_algo(). @@ -1569,96 +1568,96 @@ kex_method_diffie_hellman_group_exchange_sha256_key_exchange * */ -#define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \ -{ \ - libssh2_sha##digest_type##_ctx ctx; \ - exchange_state->exchange_hash = (void *)&ctx; \ - (void)libssh2_sha##digest_type##_init(&ctx); \ - if(session->local.banner) { \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)(strlen((char *) session->local.banner) - 2)); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - (char *) session->local.banner, \ - strlen((char *) \ - session->local.banner) \ - - 2); \ - } \ - else { \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - LIBSSH2_SSH_DEFAULT_BANNER, \ +#define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \ +do { \ + libssh2_sha##digest_type##_ctx ctx; \ + exchange_state->exchange_hash = (void *)&ctx; \ + (void)libssh2_sha##digest_type##_init(&ctx); \ + if(session->local.banner) { \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)(strlen((char *) session->local.banner) - 2)); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + (char *) session->local.banner, \ + strlen((char *) \ + session->local.banner) \ + - 2); \ + } \ + else { \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + LIBSSH2_SSH_DEFAULT_BANNER, \ sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \ - - 1); \ - } \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)strlen((char *) session->remote.banner)); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->remote.banner, \ - strlen((char *) \ - session->remote.banner)); \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)session->local.kexinit_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->local.kexinit, \ - session->local.kexinit_len); \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)session->remote.kexinit_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->remote.kexinit, \ - session->remote.kexinit_len); \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - session->server_hostkey_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->server_hostkey, \ - session->server_hostkey_len); \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)public_key_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - public_key, \ - public_key_len); \ - \ - _libssh2_htonu32(exchange_state->h_sig_comp, \ - (uint32_t)server_public_key_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - server_public_key, \ - server_public_key_len); \ - \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->k_value, \ - exchange_state->k_value_len); \ - \ - libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \ - \ - if(session->hostkey-> \ - sig_verify(session, exchange_state->h_sig, \ - exchange_state->h_sig_len, exchange_state->h_sig_comp, \ - SHA##digest_type##_DIGEST_LENGTH, \ - &session->server_hostkey_abstract)) { \ - rc = -1; \ - } \ -} \ + - 1); \ + } \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)strlen((char *) session->remote.banner)); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->remote.banner, \ + strlen((char *) \ + session->remote.banner)); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)session->local.kexinit_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->local.kexinit, \ + session->local.kexinit_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)session->remote.kexinit_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->remote.kexinit, \ + session->remote.kexinit_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + session->server_hostkey_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->server_hostkey, \ + session->server_hostkey_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)public_key_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + public_key, \ + public_key_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + (uint32_t)server_public_key_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + server_public_key, \ + server_public_key_len); \ + \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->k_value, \ + exchange_state->k_value_len); \ + \ + libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \ + \ + if(session->hostkey-> \ + sig_verify(session, exchange_state->h_sig, \ + exchange_state->h_sig_len, exchange_state->h_sig_comp, \ + SHA##digest_type##_DIGEST_LENGTH, \ + &session->server_hostkey_abstract)) { \ + rc = -1; \ + } \ +} while(0) #if LIBSSH2_ECDSA @@ -3105,17 +3104,19 @@ kex_method_list(unsigned char *buf, uint32_t list_strlen, (uint32_t)((prefvar) ? strlen(prefvar) : \ kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) -#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ - if(prefvar) { \ - _libssh2_htonu32((buf), (prefvarlen)); \ - buf += 4; \ - memcpy((buf), (prefvar), (prefvarlen)); \ - buf += (prefvarlen); \ - } \ - else { \ - buf += kex_method_list((buf), (prefvarlen), \ - (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ - } +#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ + do { \ + if(prefvar) { \ + _libssh2_htonu32((buf), (prefvarlen)); \ + buf += 4; \ + memcpy((buf), (prefvar), (prefvarlen)); \ + buf += (prefvarlen); \ + } \ + else { \ + buf += kex_method_list((buf), (prefvarlen), \ + (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ + } \ + } while(0) /* kexinit * Send SSH_MSG_KEXINIT packet diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 58a37557..d1c09b5a 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -155,7 +155,7 @@ #define libssh2_hmac_final(ctx, data) \ memcpy(data, gcry_md_read(ctx, 0), \ gcry_md_get_algo_dlen(gcry_md_get_algo(ctx))) -#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); +#define libssh2_hmac_cleanup(ctx) gcry_md_close(*ctx) #define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) #define libssh2_crypto_exit() diff --git a/src/mbedtls.c b/src/mbedtls.c index 366f7c22..90c8ce09 100644 --- a/src/mbedtls.c +++ b/src/mbedtls.c @@ -1033,17 +1033,16 @@ cleanup: return rc; } -#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \ -{ \ - unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \ - \ - if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \ - rc = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hsh, \ - SHA##digest_type##_DIGEST_LENGTH, \ - &ctx->MBEDTLS_PRIVATE(Q), &pr, &ps); \ - } \ - \ -} +#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \ + do { \ + unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \ + \ + if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \ + rc = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hsh, \ + SHA##digest_type##_DIGEST_LENGTH, \ + &ctx->MBEDTLS_PRIVATE(Q), &pr, &ps); \ + } \ + } while(0) /* _libssh2_ecdsa_sign * diff --git a/src/openssl.c b/src/openssl.c index dd00b22a..baff5194 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -410,14 +410,13 @@ _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx, return (ret == 1) ? 0 : -1; } -#define LIBSSH2_ECDSA_VERIFY(digest_type) \ -{ \ - unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ - libssh2_sha##digest_type(m, m_len, hash); \ - ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \ - ecdsa_sig, ec_key); \ - \ -} +#define LIBSSH2_ECDSA_VERIFY(digest_type) \ + do { \ + unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ + libssh2_sha##digest_type(m, m_len, hash); \ + ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \ + ecdsa_sig, ec_key); \ + } while(0) int _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx, diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e7925233..f92bf631 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -56,19 +56,19 @@ set(TESTS ) if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR CRYPTO_BACKEND STREQUAL "wolfSSL") + list(APPEND TESTS + public_key_auth_succeeds_with_correct_rsa_openssh_key + ) + if(OPENSSL_VERSION VERSION_GREATER "1.1.0" OR CRYPTO_BACKEND STREQUAL "wolfSSL") list(APPEND TESTS - public_key_auth_succeeds_with_correct_rsa_openssh_key + public_key_auth_succeeds_with_correct_ed25519_key + public_key_auth_succeeds_with_correct_encrypted_ed25519_key + public_key_auth_succeeds_with_correct_ed25519_key_from_mem + public_key_auth_succeeds_with_correct_ecdsa_key + public_key_auth_succeeds_with_correct_signed_ecdsa_key + public_key_auth_succeeds_with_correct_signed_rsa_key ) - if(OPENSSL_VERSION VERSION_GREATER "1.1.0" OR CRYPTO_BACKEND STREQUAL "wolfSSL") - list(APPEND TESTS - public_key_auth_succeeds_with_correct_ed25519_key - public_key_auth_succeeds_with_correct_encrypted_ed25519_key - public_key_auth_succeeds_with_correct_ed25519_key_from_mem - public_key_auth_succeeds_with_correct_ecdsa_key - public_key_auth_succeeds_with_correct_signed_ecdsa_key - public_key_auth_succeeds_with_correct_signed_rsa_key - ) - endif() + endif() endif() if(NOT CRYPTO_BACKEND STREQUAL "mbedTLS") @@ -83,10 +83,11 @@ target_compile_definitions(runner PRIVATE FIXTURE_WORKDIR="${CMAKE_CURRENT_SOURC # test building against shared libssh2 lib if(BUILD_SHARED_LIBS) - set(test warmup) # any test will do - add_executable(test_${test}_shared test_${test}.c) - target_include_directories(test_${test}_shared PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src" ../src) - target_link_libraries(test_${test}_shared runner ${LIB_SHARED} ${LIBRARIES}) + foreach(test simple ssh2) + add_executable(test_${test}_shared ${test}.c) + target_include_directories(test_${test}_shared PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src" ../src) + target_link_libraries(test_${test}_shared ${LIB_SHARED} ${LIBRARIES}) + endforeach() endif() foreach(test ${TESTS}) @@ -142,7 +143,7 @@ target_include_directories(test_keyboard_interactive_auth_info_request PRIVATE " find_program(GCOV_PATH gcov) set(TGT_OPTIONS -g --coverage -fprofile-abs-path) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - set(TGT_OPTIONS -g --coverage) + set(TGT_OPTIONS -g --coverage) endif() if(CMAKE_COMPILER_IS_GNUCC AND GCOV_PATH) target_compile_options(test_keyboard_interactive_auth_info_request BEFORE PRIVATE diff --git a/tests/openssh_fixture.c b/tests/openssh_fixture.c index afbbdaa4..b3185739 100644 --- a/tests/openssh_fixture.c +++ b/tests/openssh_fixture.c @@ -66,8 +66,9 @@ static int have_docker = 0; static int run_command_varg(char **output, const char *command, va_list args) { + static const char redirect_stderr[] = "%s 2>&1"; + FILE *pipe; - char redirect_stderr[] = "%s 2>&1"; char command_buf[BUFSIZ]; char buf[BUFSIZ]; int ret; diff --git a/tests/session_fixture.c b/tests/session_fixture.c index 232c0498..24a6aa1e 100644 --- a/tests/session_fixture.c +++ b/tests/session_fixture.c @@ -58,8 +58,8 @@ #endif #include -LIBSSH2_SESSION *connected_session = NULL; -libssh2_socket_t connected_socket = LIBSSH2_INVALID_SOCKET; +static LIBSSH2_SESSION *connected_session = NULL; +static libssh2_socket_t connected_socket = LIBSSH2_INVALID_SOCKET; static int connect_to_server(void) { diff --git a/tests/simple.c b/tests/simple.c index 450fd568..33e26f25 100644 --- a/tests/simple.c +++ b/tests/simple.c @@ -46,11 +46,11 @@ static int test_libssh2_base64_decode(LIBSSH2_SESSION *session) char *data; unsigned int datalen; const char *src = "Zm5vcmQ="; - unsigned int src_len = strlen(src); + size_t src_len = strlen(src); int ret; ret = libssh2_base64_decode(session, &data, &datalen, - src, src_len); + src, (unsigned int)src_len); if(ret) return ret; diff --git a/tests/ssh2.c b/tests/ssh2.c index 84b95ca7..4d9bbc57 100644 --- a/tests/ssh2.c +++ b/tests/ssh2.c @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) * and setup crypto, compression, and MAC layers */ session = libssh2_session_init(); - if(libssh2_session_startup(session, sock)) { + if(libssh2_session_handshake(session, sock)) { fprintf(stderr, "Failure establishing SSH session\n"); return 1; } diff --git a/tests/test_agent_forward_succeeds.c b/tests/test_agent_forward_succeeds.c index 7d835feb..361c4c21 100644 --- a/tests/test_agent_forward_succeeds.c +++ b/tests/test_agent_forward_succeeds.c @@ -1,8 +1,8 @@ #include "runner.h" -const char *USERNAME = "libssh2"; /* set in Dockerfile */ -const char *KEY_FILE_PRIVATE = "key_rsa"; -const char *KEY_FILE_PUBLIC = "key_rsa.pub"; /* set in Dockerfile */ +static const char *USERNAME = "libssh2"; /* set in Dockerfile */ +static const char *KEY_FILE_PRIVATE = "key_rsa"; +static const char *KEY_FILE_PUBLIC = "key_rsa.pub"; /* set in Dockerfile */ int test(LIBSSH2_SESSION *session) { diff --git a/tests/test_keyboard_interactive_auth_info_request.c b/tests/test_keyboard_interactive_auth_info_request.c index 8fbdc2f2..8683f9fe 100644 --- a/tests/test_keyboard_interactive_auth_info_request.c +++ b/tests/test_keyboard_interactive_auth_info_request.c @@ -55,7 +55,8 @@ struct test_case { }; #define TEST_CASES_LEN 16 -struct test_case test_cases[TEST_CASES_LEN] = { +static const struct test_case + test_cases[TEST_CASES_LEN] = { /* too small */ { NULL, 0, @@ -191,7 +192,8 @@ struct test_case test_cases[TEST_CASES_LEN] = { }; #define FAILED_MALLOC_TEST_CASES_LEN 2 -struct test_case failed_malloc_test_cases[FAILED_MALLOC_TEST_CASES_LEN] = { +static const struct test_case + failed_malloc_test_cases[FAILED_MALLOC_TEST_CASES_LEN] = { /* malloc fail */ { "<" @@ -298,7 +300,8 @@ int main(void) for(i = 0; i < TEST_CASES_LEN; i++) { test_case(i + 1, - test_cases[i].data, test_cases[i].data_len, + test_cases[i].data, + test_cases[i].data_len, NULL, test_cases[i].expected); } diff --git a/tests/test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c b/tests/test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c index b9d9385f..04ae61b6 100644 --- a/tests/test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c +++ b/tests/test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c @@ -5,7 +5,7 @@ static const char *USERNAME = "libssh2"; /* set in Dockerfile */ static const char *KEY_FILE_ED25519_PRIVATE = "key_ed25519"; -int read_file(const char *path, char **buf, size_t *len); +static int read_file(const char *path, char **buf, size_t *len); int test(LIBSSH2_SESSION *session) { @@ -48,7 +48,7 @@ int test(LIBSSH2_SESSION *session) return 0; } -int read_file(const char *path, char **out_buffer, size_t *out_len) +static int read_file(const char *path, char **out_buffer, size_t *out_len) { FILE *fp = NULL; char *buffer = NULL;