From 399c639c92b4c5f125ba09f47400f8ae39061a3c Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 25 Dec 2023 11:59:59 -0800 Subject: [PATCH] Update to rra-c-util 10.5 * Assume a working snprintf rather than supplying a replacement. * Fix detection of reallocarray on NetBSD. * Check that Kerberos header files were found during configure. * Use AS_ECHO in all Autoconf macros. * Always use lib32 or lib64 if it exists, even on Debian. * Fix rejection of unknown Clang warning flags. * Disable -Wreserved-identifier for Clang warning builds. Reformat and restructure Perl code for new perlcritic and perltidy rules. heimdal-history now requires the Perl modules Const::Fast and JSON::MaybeXS instead of Readonly and JSON. --- .clang-format | 25 +- .gitignore | 1 + Makefile.am | 28 +- NEWS | 15 + README | 4 +- configure.ac | 11 +- m4/cc-flags.m4 | 44 +- m4/clang.m4 | 2 + m4/krb5-config.m4 | 14 +- m4/krb5.m4 | 106 +-- m4/lib-depends.m4 | 5 +- m4/lib-helper.m4 | 2 + m4/lib-pathname.m4 | 23 +- m4/snprintf.m4 | 62 -- m4/sqlite.m4 | 80 --- m4/sqlite3.m4 | 91 +++ m4/tinycdb.m4 | 2 + m4/vamacros.m4 | 2 + plugin/cracklib.c | 7 +- plugin/general.c | 9 +- plugin/internal.h | 7 +- plugin/principal.c | 7 +- plugin/sqlite.c | 8 +- plugin/vector.c | 4 +- portable/macros.h | 12 +- portable/snprintf.c | 992 ---------------------------- portable/stdbool.h | 4 +- portable/strndup.c | 2 +- portable/system.h | 19 +- tests/TESTS | 3 +- tests/data/cppcheck.supp | 34 +- tests/data/passwords/make-c-data | 18 +- tests/data/perlcriticrc | 38 +- tests/data/perltidyrc | 9 +- tests/data/valgrind.supp | 10 +- tests/docs/pod-spelling-t | 4 +- tests/docs/pod-t | 4 +- tests/docs/spdx-license-t | 12 +- tests/perl/critic-t | 18 +- tests/perl/minimum-version-t | 4 +- tests/perl/strict-t | 4 +- tests/plugin/heimdal-t.c | 7 +- tests/plugin/mit-t.c | 8 +- tests/portable/snprintf-t.c | 188 ------ tests/portable/snprintf.c | 2 - tests/runtests.c | 38 +- tests/style/obsolete-strings-t | 7 +- tests/tap/basic.c | 8 +- tests/tap/basic.h | 28 +- tests/tap/kerberos.c | 21 +- tests/tap/kerberos.h | 11 +- tests/tap/macros.h | 12 +- tests/tap/perl/Test/RRA.pm | 28 +- tests/tap/perl/Test/RRA/Automake.pm | 32 +- tests/tap/perl/Test/RRA/Config.pm | 22 +- tests/tap/process.c | 5 +- tests/tools/heimdal-history-t | 30 +- tests/tools/heimdal-strength-t | 38 +- tests/tools/wordlist-sqlite-t | 16 +- tests/tools/wordlist-t | 14 +- tests/valgrind/logs-t | 4 +- tools/heimdal-history | 70 +- tools/krb5-strength-wordlist | 16 +- util/macros.h | 6 +- util/xmalloc.c | 37 +- util/xmalloc.h | 14 +- 66 files changed, 706 insertions(+), 1702 deletions(-) delete mode 100644 m4/snprintf.m4 delete mode 100644 m4/sqlite.m4 create mode 100644 m4/sqlite3.m4 delete mode 100644 portable/snprintf.c delete mode 100644 tests/portable/snprintf-t.c delete mode 100644 tests/portable/snprintf.c diff --git a/.clang-format b/.clang-format index 993594c..b245fdd 100644 --- a/.clang-format +++ b/.clang-format @@ -1,9 +1,11 @@ # Configuration for clang-format automated reformatting. -*- yaml -*- # +# This configuration requires Clang 13.0 or later. +# # The canonical version of this file is maintained in the rra-c-util package, # which can be found at . # -# Copyright 2020 Russ Allbery +# Copyright 2020-2021 Russ Allbery # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice @@ -15,8 +17,10 @@ --- Language: Cpp BasedOnStyle: LLVM -AlignConsecutiveMacros: true +AlignArrayOfStructures: Left +AlignConsecutiveMacros: AcrossEmptyLinesAndComments AlignEscapedNewlines: Left +AllowShortEnumsOnASingleLine: false AlwaysBreakAfterReturnType: AllDefinitions BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: WebKit @@ -27,3 +31,20 @@ IndentWrappedFunctionNames: false MaxEmptyLinesToKeep: 2 SpaceAfterCStyleCast: true --- + +# Additional formatting options that we would like to use but cannot (at least +# yet): +# +# PPIndentWidth: 1 +# Better indentation of #if blocks, but unfortunately in Clang 13.0 this +# indentation is also applied to code in #define macros, so produces: +# +# #define ENTRY(args, flags) \ +# do { \ +# if (args->debug) \ +# putil_log_entry((args), __func__, (flags)); \ +# } while (0) +# +# Should be used as soon as there is a way to distinguish between +# identation of the preprocessor directives themselves and the code blocks +# in #define. diff --git a/.gitignore b/.gitignore index dd75eb3..99a0f85 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /config.log /config.status /configure +/configure~ /cracklib/packer /docs/krb5-strength.5.in /libtool diff --git a/Makefile.am b/Makefile.am index 10b96dd..c6cc7b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Automake makefile for krb5-strength. # # Written by Russ Allbery -# Copyright 2016, 2020 Russ Allbery +# Copyright 2016, 2020, 2023 Russ Allbery # Copyright 2007, 2009-2010, 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -32,9 +32,9 @@ EXTRA_DIST = .clang-format .github .gitignore README.md LICENSE bootstrap \ # libraries, and if we're using the system CrackLib, TinyCDB, or SQLite, add # its location unconditionally as well. AM_CPPFLAGS = $(CRACKLIB_CPPFLAGS) $(KRB5_CPPFLAGS) $(CDB_CPPFLAGS) \ - $(SQLITE_CPPFLAGS) + $(SQLITE3_CPPFLAGS) AM_LDFLAGS = $(CRACKLIB_LDFLAGS) $(KRB5_LDFLAGS) $(CDB_LDFLAGS) \ - $(SQLITE_LDFLAGS) + $(SQLITE3_LDFLAGS) # Build our portability library. noinst_LTLIBRARIES = portable/libportable.la @@ -76,7 +76,7 @@ else plugin_strength_la_LIBADD = $(CRACKLIB_LIBS) endif plugin_strength_la_LIBADD += portable/libportable.la $(KRB5_LIBS) \ - $(CDB_LIBS) $(SQLITE_LIBS) + $(CDB_LIBS) $(SQLITE3_LIBS) # The Heimdal external check program. bin_PROGRAMS = tools/heimdal-strength @@ -91,7 +91,7 @@ else tools_heimdal_strength_LDADD = $(CRACKLIB_LIBS) endif tools_heimdal_strength_LDADD += util/libutil.a portable/libportable.la \ - $(KRB5_LIBS) $(CDB_LIBS) $(SQLITE_LIBS) + $(KRB5_LIBS) $(CDB_LIBS) $(SQLITE3_LIBS) # Other tools. dist_bin_SCRIPTS = tools/heimdal-history tools/krb5-strength-wordlist @@ -134,11 +134,10 @@ warnings: KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_GCC)' $(check_PROGRAMS) # The bits below are for the test suite, not for the main package. -check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \ - tests/portable/asprintf-t tests/portable/mkstemp-t \ - tests/portable/reallocarray-t tests/portable/snprintf-t \ - tests/portable/strndup-t tests/util/messages-krb5-t \ - tests/util/messages-t tests/util/xmalloc +check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \ + tests/portable/asprintf-t tests/portable/mkstemp-t \ + tests/portable/reallocarray-t tests/portable/strndup-t \ + tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc if EMBEDDED_CRACKLIB check_PROGRAMS += cracklib/packer endif @@ -168,9 +167,6 @@ tests_portable_reallocarray_t_SOURCES = tests/portable/reallocarray-t.c \ tests/portable/reallocarray.c tests_portable_reallocarray_t_LDADD = tests/tap/libtap.a \ portable/libportable.la -tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \ - tests/portable/snprintf.c -tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la tests_portable_strndup_t_SOURCES = tests/portable/strndup-t.c \ tests/portable/strndup.c tests_portable_strndup_t_LDADD = tests/tap/libtap.a portable/libportable.la @@ -223,6 +219,6 @@ check-valgrind: $(check_PROGRAMS) tests/data/dictionary.pwd # Used by maintainers to reformat all source code using clang-format and # excluding some files. reformat: - find . -name '*.[ch]' \! -name snprintf.c \! -name krb5-profile.c \ - \! -path './cracklib/*' -print \ - | xargs clang-format-10 -style=file -i + find . -name '*.[ch]' \! -name krb5-profile.c \ + \! -path './cracklib/*' -print \ + | xargs clang-format -style=file -i diff --git a/NEWS b/NEWS index 973f5a9..ecd9377 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,20 @@ User-Visible krb5-strength Changes +krb5-strength 3.3 (unreleased) + + heimdal-history now requires the Perl modules Const::Fast and + JSON::MaybeXS instead of Readonly and JSON. + + Update to rra-c-util 10.5: + + * Assume a working snprintf rather than supplying a replacement. + * Fix detection of reallocarray on NetBSD. + * Check that Kerberos header files were found during configure. + * Use AS_ECHO in all Autoconf macros. + * Always use lib32 or lib64 if it exists, even on Debian. + * Fix rejection of unknown Clang warning flags. + * Disable -Wreserved-identifier for Clang warning builds. + krb5-strength 3.2 (2020-05-17) Add new -c (--check-only) option to heimdal-history to check whether a diff --git a/README b/README index 734022b..e557098 100644 --- a/README +++ b/README @@ -127,11 +127,11 @@ REQUIREMENTS later plus the following CPAN modules: * DB_File::Lock + * Const::Fast * Crypt::PBKDF2 * Getopt::Long::Descriptive * IPC::Run - * JSON - * Readonly + * JSON::MaybeXS and their dependencies. diff --git a/configure.ac b/configure.ac index 6400f4a..323d444 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. dnl dnl Written by Russ Allbery -dnl Copyright 2016, 2020 Russ Allbery +dnl Copyright 2016, 2020, 2023 Russ Allbery dnl Copyright 2006-2007, 2009-2010, 2012-2014 dnl The Board of Trustees of the Leland Stanford Junior University dnl @@ -29,7 +29,7 @@ AC_SYS_LARGEFILE AM_PROG_CC_C_O m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_INSTALL -AM_DISABLE_STATIC +AC_DISABLE_STATIC LT_INIT dnl Only used for the test suite. @@ -59,7 +59,7 @@ AC_LIBOBJ([krb5-extra]) AC_CHECK_HEADERS([kadm5/kadm5-pwcheck.h kadm5/kadm5_err.h], [], [], [RRA_INCLUDES_KRB5]) RRA_LIB_KRB5_RESTORE -RRA_LIB_SQLITE_OPTIONAL +RRA_LIB_SQLITE3_OPTIONAL dnl Probe for libdl, which is used for the test suite. save_LIBS="$LIBS" @@ -70,7 +70,7 @@ AC_SUBST([DL_LIBS]) dnl Checks for basic C functionality. AC_HEADER_STDBOOL AC_CHECK_HEADERS([strings.h sys/bittypes.h sys/select.h sys/time.h syslog.h]) -AC_CHECK_DECLS([snprintf, vsnprintf]) +AC_CHECK_DECLS([reallocarray]) RRA_C_C99_VAMACROS RRA_C_GNU_VAMACROS AC_TYPE_LONG_LONG_INT @@ -79,11 +79,10 @@ AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_CHECK_TYPES([ssize_t], [], [], [#include ]) -RRA_FUNC_SNPRINTF AC_CHECK_FUNCS([explicit_bzero setrlimit]) AC_REPLACE_FUNCS([asprintf mkstemp reallocarray strndup]) dnl Write out the results. AC_CONFIG_FILES([Makefile]) -AC_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADERS([config.h]) AC_OUTPUT diff --git a/m4/cc-flags.m4 b/m4/cc-flags.m4 index 9a749f7..014d0c9 100644 --- a/m4/cc-flags.m4 +++ b/m4/cc-flags.m4 @@ -1,8 +1,11 @@ +# serial 1 + dnl Check whether the compiler supports particular flags. dnl -dnl Provides RRA_PROG_CC_FLAG, which checks whether a compiler supports a -dnl given flag. If it does, the commands in the second argument are run. If -dnl not, the commands in the third argument are run. +dnl Provides RRA_PROG_CC_FLAG and RRA_PROG_LD_FLAG, which checks whether a +dnl compiler supports a given flag for either compilation or linking, +dnl respectively. If it does, the commands in the second argument are run. +dnl If not, the commands in the third argument are run. dnl dnl Provides RRA_PROG_CC_WARNINGS_FLAGS, which checks whether a compiler dnl supports a large set of warning flags and sets the WARNINGS_CFLAGS @@ -14,7 +17,7 @@ dnl dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl -dnl Copyright 2016-2020 Russ Allbery +dnl Copyright 2016-2022 Russ Allbery dnl Copyright 2006, 2009, 2016 dnl by Internet Systems Consortium, Inc. ("ISC") dnl @@ -34,17 +37,22 @@ dnl SPDX-License-Identifier: ISC dnl Used to build the result cache name. AC_DEFUN([_RRA_PROG_CC_FLAG_CACHE], -[translit([rra_cv_compiler_c_$1], [-=+], [___])]) +[translit([rra_cv_compiler_c_$1], [-=+,], [____])]) +AC_DEFUN([_RRA_PROG_LD_FLAG_CACHE], +[translit([rra_cv_linker_c_$1], [-=+,], [____])]) -dnl Check whether a given flag is supported by the compiler. +dnl Check whether a given flag is supported by the compiler when compiling a C +dnl source file. AC_DEFUN([RRA_PROG_CC_FLAG], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if $CC supports $1]) AC_CACHE_VAL([_RRA_PROG_CC_FLAG_CACHE([$1])], [save_CFLAGS=$CFLAGS + AS_IF([test x"$CLANG" = xyes], + [CFLAGS="$CFLAGS -Werror=unknown-warning-option"]) AS_CASE([$1], - [-Wno-*], [CFLAGS="$CFLAGS `echo "$1" | sed 's/-Wno-/-W/'`"], - [*], [CFLAGS="$CFLAGS $1"]) + [-Wno-*], [CFLAGS="$CFLAGS `AS_ECHO(["$1"]) | sed 's/-Wno-/-W/'`"], + [CFLAGS="$CFLAGS $1"]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [int foo = 0;])], [_RRA_PROG_CC_FLAG_CACHE([$1])=yes], [_RRA_PROG_CC_FLAG_CACHE([$1])=no]) @@ -52,6 +60,23 @@ AC_DEFUN([RRA_PROG_CC_FLAG], AC_MSG_RESULT([$_RRA_PROG_CC_FLAG_CACHE([$1])]) AS_IF([test x"$_RRA_PROG_CC_FLAG_CACHE([$1])" = xyes], [$2], [$3])]) +dnl Check whether a given flag is supported by the compiler when linking an +dnl executable. +AC_DEFUN([RRA_PROG_LD_FLAG], +[AC_REQUIRE([AC_PROG_CC]) + AC_MSG_CHECKING([if $CC supports $1 for linking]) + AC_CACHE_VAL([_RRA_PROG_LD_FLAG_CACHE([$1])], + [save_LDFLAGS=$LDFLAGS + AS_IF([test x"$CLANG" = xyes], + [LDFLAGS="$LDFLAGS -Werror=unknown-warning-option"]) + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [int foo = 0;])], + [_RRA_PROG_LD_FLAG_CACHE([$1])=yes], + [_RRA_PROG_LD_FLAG_CACHE([$1])=no]) + LDFLAGS=$save_LDFLAGS]) + AC_MSG_RESULT([$_RRA_PROG_LD_FLAG_CACHE([$1])]) + AS_IF([test x"$_RRA_PROG_LD_FLAG_CACHE([$1])" = xyes], [$2], [$3])]) + dnl Determine the full set of viable warning flags for the current compiler. dnl dnl This is based partly on personal preference and is a fairly aggressive set @@ -73,6 +98,7 @@ dnl -Wcast-qual Some structs require casting away const dnl -Wdisabled-macro-expansion Triggers on libc (sigaction.sa_handler) dnl -Wpadded Not an actual problem dnl -Wreserved-id-macros Autoconf sets several of these normally +dnl -Wreserved-identifer False positive with FD_ZERO dnl -Wsign-conversion Too many fiddly changes for the benefit dnl -Wtautological-pointer-compare False positives with for loops dnl -Wundef Conflicts with Autoconf probe results @@ -88,7 +114,7 @@ AC_DEFUN([RRA_PROG_CC_WARNINGS_FLAGS], [WARNINGS_CFLAGS="-Werror" m4_foreach_w([flag], [-Weverything -Wno-cast-qual -Wno-disabled-macro-expansion -Wno-padded - -Wno-sign-conversion -Wno-reserved-id-macro + -Wno-sign-conversion -Wno-reserved-id-macro -Wno-reserved-identifier -Wno-tautological-pointer-compare -Wno-undef -Wno-unreachable-code -Wno-unreachable-code-return -Wno-unused-macros -Wno-used-but-marked-unused], diff --git a/m4/clang.m4 b/m4/clang.m4 index c1815a5..18ec056 100644 --- a/m4/clang.m4 +++ b/m4/clang.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Determine whether the current compiler is Clang. dnl dnl If the current compiler is Clang, set the shell variable CLANG to yes. diff --git a/m4/krb5-config.m4 b/m4/krb5-config.m4 index bbfcdc1..8f8123c 100644 --- a/m4/krb5-config.m4 +++ b/m4/krb5-config.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Use krb5-config to get link paths for Kerberos libraries. dnl dnl Provides one macro, RRA_KRB5_CONFIG, which attempts to get compiler and @@ -11,7 +13,7 @@ dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl dnl Written by Russ Allbery -dnl Copyright 2018 Russ Allbery +dnl Copyright 2018, 2021-2022 Russ Allbery dnl Copyright 2011-2012 dnl The Board of Trustees of the Leland Stanford Junior University dnl @@ -86,9 +88,9 @@ AC_DEFUN([RRA_KRB5_CONFIG], rra_krb5_config_$3="$PATH_KRB5_CONFIG"]) AS_IF([test x"$rra_krb5_config_$3" != x && test -x "$rra_krb5_config_$3"], [AC_CACHE_CHECK([for $2 support in krb5-config], [rra_cv_lib_$3[]_config], - [AS_IF(["$rra_krb5_config_$3" 2>&1 | grep $2 >/dev/null 2>&1], - [rra_cv_lib_$3[]_config=yes], - [rra_cv_lib_$3[]_config=no])]) + [AS_IF(["$rra_krb5_config_$3" 2>&1 | grep $2 >/dev/null 2>&1], + [rra_cv_lib_$3[]_config=yes], + [rra_cv_lib_$3[]_config=no])]) AS_IF([test "$rra_cv_lib_$3[]_config" = yes], [$3[]_CPPFLAGS=`"$rra_krb5_config_$3" --cflags $2 2>/dev/null` _RRA_KRB5_CONFIG_LIBS([$rra_krb5_config_$3], [$2], [$3]) @@ -98,7 +100,7 @@ AC_DEFUN([RRA_KRB5_CONFIG], $3[]_LIBS=`"$rra_krb5_config_$3" --libs $2 2>/dev/null` rra_krb5_config_$3[]_ok=yes])])]) AS_IF([test x"$rra_krb5_config_$3[]_ok" = xyes], - [$3[]_CPPFLAGS=`echo "$$3[]_CPPFLAGS" | sed 's%-I/usr/include %%'` - $3[]_CPPFLAGS=`echo "$$3[]_CPPFLAGS" | sed 's%-I/usr/include$%%'` + [$3[]_CPPFLAGS=`AS_ECHO(["$$3[]_CPPFLAGS"]) | sed 's%-I/usr/include %%'` + $3[]_CPPFLAGS=`AS_ECHO(["$$3[]_CPPFLAGS"]) | sed 's%-I/usr/include$%%'` $4], [$5])]) diff --git a/m4/krb5.m4 b/m4/krb5.m4 index 617c27b..9469d51 100644 --- a/m4/krb5.m4 +++ b/m4/krb5.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Find the compiler and linker flags for Kerberos. dnl dnl Finds the compiler and linker flags for linking with Kerberos libraries. @@ -17,9 +19,9 @@ dnl dnl If KRB5_CPPFLAGS, KRB5_LDFLAGS, or KRB5_LIBS are set before calling these dnl macros, their values will be added to whatever the macros discover. dnl -dnl KRB5_CPPFLAGS_GCC will be set to the same value as KRB5_CPPFLAGS but with -dnl any occurrences of -I changed to -isystem. This may be useful to suppress -dnl warnings from the Kerberos header files when building with GCC and +dnl KRB5_CPPFLAGS_WARNINGS will be set to the same value as KRB5_CPPFLAGS but +dnl with any occurrences of -I changed to -isystem. This may be useful to +dnl suppress warnings from the Kerberos header files when building with and dnl aggressive warning flags. Be aware that this change will change the dnl compiler header file search order as well. dnl @@ -50,7 +52,7 @@ dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl dnl Written by Russ Allbery -dnl Copyright 2018 Russ Allbery +dnl Copyright 2018, 2020-2022 Russ Allbery dnl Copyright 2005-2011, 2013-2014 dnl The Board of Trustees of the Leland Stanford Junior University dnl @@ -60,9 +62,6 @@ dnl notice is preserved. dnl dnl SPDX-License-Identifier: FSFULLR -dnl Ignore Automake conditionals if not using Automake. -m4_define_default([AM_CONDITIONAL], [:]) - dnl Headers to include when probing for Kerberos library properties. AC_DEFUN([RRA_INCLUDES_KRB5], [[ #if HAVE_KRB5_H @@ -109,13 +108,14 @@ dnl Check for a header using a file existence check rather than using dnl AC_CHECK_HEADERS. This is used if there were arguments to configure dnl specifying the Kerberos header path, since we may have one header in the dnl default include path and another under our explicitly-configured Kerberos -dnl location. +dnl location. The second argument is run if the header was found. AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER], [AC_MSG_CHECKING([for $1]) AS_IF([test -f "${rra_krb5_incroot}/$1"], [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), [1], [Define to 1 if you have the <$1> header file.]) - AC_MSG_RESULT([yes])], + AC_MSG_RESULT([yes]) + $2], [AC_MSG_RESULT([no])])]) dnl Check for the com_err header. Internal helper macro since we need @@ -127,13 +127,20 @@ AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR], _RRA_LIB_KRB5_CHECK_HEADER([kerberosv5/com_err.h])])]) dnl Check for the main Kerberos header. Internal helper macro since we need -dnl to do the same checks in multiple places. +dnl to do the same checks in multiple places. The first argument is run if +dnl some header was found, and the second if no header was found. AC_DEFUN([_RRA_LIB_KRB5_CHECK_HEADER_KRB5], -[AS_IF([test x"$rra_krb5_incroot" = x], - [AC_CHECK_HEADERS([krb5.h kerberosv5/krb5.h krb5/krb5.h])], - [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h]) - _RRA_LIB_KRB5_CHECK_HEADER([kerberosv5/krb5.h]) - _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h])])]) +[rra_krb5_found_header= + AS_IF([test x"$rra_krb5_incroot" = x], + [AC_CHECK_HEADERS([krb5.h kerberosv5/krb5.h krb5/krb5.h], + [rra_krb5_found_header=true])], + [_RRA_LIB_KRB5_CHECK_HEADER([krb5.h], + [rra_krb5_found_header=true]) + _RRA_LIB_KRB5_CHECK_HEADER([kerberosv5/krb5.h], + [rra_krb5_found_header=true]) + _RRA_LIB_KRB5_CHECK_HEADER([krb5/krb5.h], + [rra_krb5_found_header=true])]) + AS_IF([test x"$rra_krb5_found_header" = xtrue], [$1], [$2])]) dnl Does the appropriate library checks for reduced-dependency Kerberos dnl linkage. The single argument, if true, says to fail if Kerberos could not @@ -143,7 +150,6 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED], AC_CHECK_LIB([krb5], [krb5_init_context], [KRB5_LIBS="-lkrb5" LIBS="$KRB5_LIBS $LIBS" - _RRA_LIB_KRB5_CHECK_HEADER_KRB5 AC_CHECK_FUNCS([krb5_get_error_message], [AC_CHECK_FUNCS([krb5_free_error_message])], [AC_CHECK_FUNCS([krb5_get_error_string], [], @@ -156,11 +162,17 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED], [AC_CHECK_LIB([com_err], [com_err], [KRB5_LIBS="$KRB5_LIBS -lcom_err"], [AS_IF([test x"$1" = xtrue], - [AC_MSG_ERROR([cannot find usable com_err library])], + [AC_MSG_ERROR( + [cannot find usable com_err library])], [KRB5_LIBS=""])]) - _RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])])], - [AS_IF([test x"$1" = xtrue], - [AC_MSG_ERROR([cannot find usable Kerberos library])])]) + _RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])]) + _RRA_LIB_KRB5_CHECK_HEADER_KRB5([], + [KRB5_CPPFLAGS= + KRB5_LIBS= + AS_IF([test x"$1" = xtrue], + [AC_MSG_ERROR([cannot find usable Kerberos header])])])], + [AS_IF([test x"$1" = xtrue], + [AC_MSG_ERROR([cannot find usable Kerberos library])])]) RRA_LIB_KRB5_RESTORE]) dnl Does the appropriate library checks for Kerberos linkage when we don't @@ -207,15 +219,19 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL], [$rra_krb5_extra])], [-lasn1 -lcom_err -lcrypto $rra_krb5_extra]) LIBS="$KRB5_LIBS $LIBS" - _RRA_LIB_KRB5_CHECK_HEADER_KRB5 AC_CHECK_FUNCS([krb5_get_error_message], - [AC_CHECK_FUNCS([krb5_free_error_message])], - [AC_CHECK_FUNCS([krb5_get_error_string], [], - [AC_CHECK_FUNCS([krb5_get_err_txt], [], - [AC_CHECK_FUNCS([krb5_svc_get_msg], - [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [], - [RRA_INCLUDES_KRB5])], - [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])]) + [AC_CHECK_FUNCS([krb5_free_error_message])], + [AC_CHECK_FUNCS([krb5_get_error_string], [], + [AC_CHECK_FUNCS([krb5_get_err_txt], [], + [AC_CHECK_FUNCS([krb5_svc_get_msg], + [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [], + [RRA_INCLUDES_KRB5])], + [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])]) + _RRA_LIB_KRB5_CHECK_HEADER_KRB5([], + [KRB5_CPPFLAGS= + KRB5_LIBS= + AS_IF([test x"$1" = xtrue], + [AC_MSG_ERROR([cannot find usable Kerberos header])])]) RRA_LIB_KRB5_RESTORE]) dnl Sanity-check the results of krb5-config and be sure we can really link a @@ -225,7 +241,12 @@ dnl check. AC_DEFUN([_RRA_LIB_KRB5_CHECK], [RRA_LIB_KRB5_SWITCH AC_CHECK_FUNC([krb5_init_context], - [RRA_LIB_KRB5_RESTORE], + [_RRA_LIB_KRB5_CHECK_HEADER_KRB5([RRA_LIB_KRB5_RESTORE], + [RRA_LIB_KRB5_RESTORE + KRB5_CPPFLAGS= + KRB5_LIBS= + _RRA_LIB_KRB5_PATHS + _RRA_LIB_KRB5_MANUAL([$1])])], [RRA_LIB_KRB5_RESTORE KRB5_CPPFLAGS= KRB5_LIBS= @@ -239,15 +260,14 @@ AC_DEFUN([_RRA_LIB_KRB5_CONFIG], [RRA_KRB5_CONFIG([${rra_krb5_root}], [krb5], [KRB5], [_RRA_LIB_KRB5_CHECK([$1]) RRA_LIB_KRB5_SWITCH - _RRA_LIB_KRB5_CHECK_HEADER_KRB5 AC_CHECK_FUNCS([krb5_get_error_message], - [AC_CHECK_FUNCS([krb5_free_error_message])], - [AC_CHECK_FUNCS([krb5_get_error_string], [], - [AC_CHECK_FUNCS([krb5_get_err_txt], [], - [AC_CHECK_FUNCS([krb5_svc_get_msg], - [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [], - [RRA_INCLUDES_KRB5])], - [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])]) + [AC_CHECK_FUNCS([krb5_free_error_message])], + [AC_CHECK_FUNCS([krb5_get_error_string], [], + [AC_CHECK_FUNCS([krb5_get_err_txt], [], + [AC_CHECK_FUNCS([krb5_svc_get_msg], + [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h], [], [], + [RRA_INCLUDES_KRB5])], + [_RRA_LIB_KRB5_CHECK_HEADER_COM_ERR])])])]) RRA_LIB_KRB5_RESTORE], [_RRA_LIB_KRB5_PATHS _RRA_LIB_KRB5_MANUAL([$1])])]) @@ -260,7 +280,7 @@ AC_DEFUN([_RRA_LIB_KRB5_INTERNAL], [AC_REQUIRE([RRA_ENABLE_REDUCED_DEPENDS]) rra_krb5_incroot= AC_SUBST([KRB5_CPPFLAGS]) - AC_SUBST([KRB5_CPPFLAGS_GCC]) + AC_SUBST([KRB5_CPPFLAGS_WARNINGS]) AC_SUBST([KRB5_LDFLAGS]) AC_SUBST([KRB5_LIBS]) AS_IF([test x"$rra_krb5_includedir" != x], @@ -278,7 +298,7 @@ AC_DEFUN([_RRA_LIB_KRB5_INTERNAL], AS_CASE([$KRB5_LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true]) AM_CONDITIONAL([KRB5_USES_COM_ERR], [test x"$rra_krb5_uses_com_err" = xtrue]) - KRB5_CPPFLAGS_GCC=`echo "$KRB5_CPPFLAGS" | sed -e 's/-I/-isystem /g'`]) + KRB5_CPPFLAGS_WARNINGS=`AS_ECHO(["$KRB5_CPPFLAGS"]) | sed 's/-I/-isystem /g'`]) dnl The main macro for packages with mandatory Kerberos support. AC_DEFUN([RRA_LIB_KRB5], @@ -331,10 +351,10 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL], [rra_krb5_libdir="$withval"])]) AS_IF([test x"$rra_use_KRB5" != xfalse], - [AS_IF([test x"$rra_use_KRB5" = xtrue], - [_RRA_LIB_KRB5_INTERNAL([true])], - [_RRA_LIB_KRB5_INTERNAL([false])])], - [AM_CONDITIONAL([KRB5_USES_COM_ERR], [false])]) + [AS_IF([test x"$rra_use_KRB5" = xtrue], + [_RRA_LIB_KRB5_INTERNAL([true])], + [_RRA_LIB_KRB5_INTERNAL([false])])], + [AM_CONDITIONAL([KRB5_USES_COM_ERR], [false])]) AS_IF([test x"$KRB5_LIBS" != x], [rra_use_KRB5=true AC_DEFINE([HAVE_KRB5], 1, [Define to enable Kerberos features.])])]) diff --git a/m4/lib-depends.m4 b/m4/lib-depends.m4 index 09a2cf9..dd307eb 100644 --- a/m4/lib-depends.m4 +++ b/m4/lib-depends.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Provides option to change library probes. dnl dnl This file provides RRA_ENABLE_REDUCED_DEPENDS, which adds the configure @@ -13,6 +15,7 @@ dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl dnl Written by Russ Allbery +dnl Copyright 2022 Russ Allbery dnl Copyright 2005-2007 dnl The Board of Trustees of the Leland Stanford Junior University dnl @@ -24,7 +27,7 @@ dnl SPDX-License-Identifier: FSFULLR AC_DEFUN([RRA_ENABLE_REDUCED_DEPENDS], [rra_reduced_depends=false -AC_ARG_ENABLE([reduced-depends], + AC_ARG_ENABLE([reduced-depends], [AS_HELP_STRING([--enable-reduced-depends], [Try to minimize shared library dependencies])], [AS_IF([test x"$enableval" = xyes], [rra_reduced_depends=true])])]) diff --git a/m4/lib-helper.m4 b/m4/lib-helper.m4 index 481122b..28226b2 100644 --- a/m4/lib-helper.m4 +++ b/m4/lib-helper.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Helper functions to manage compiler variables. dnl dnl These are a wide variety of helper macros to make it easier to construct diff --git a/m4/lib-pathname.m4 b/m4/lib-pathname.m4 index 46e8879..e5ffbd7 100644 --- a/m4/lib-pathname.m4 +++ b/m4/lib-pathname.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Determine the library path name. dnl dnl Red Hat systems and some other Linux systems use lib64 and lib32 rather @@ -9,13 +11,11 @@ dnl the compilation environment. If a suffix is given, a slash and that dnl suffix will be appended, to allow for adding a subdirectory of the library dnl directory. dnl -dnl This file also provides the Autoconf macro RRA_SET_LIBDIR, which sets the -dnl libdir variable to PREFIX/lib{,32,64} as appropriate. -dnl dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl dnl Written by Russ Allbery +dnl Copyright 2021-2022 Russ Allbery dnl Copyright 2008-2009 dnl The Board of Trustees of the Leland Stanford Junior University dnl @@ -37,10 +37,10 @@ dnl see. AC_DEFUN([_RRA_LIB_ARCH_NAME], [rra_lib_arch_name=lib AC_CHECK_SIZEOF([long]) - AS_IF([test "$ac_cv_sizeof_long" -eq 4 && test -d /usr/lib32], - [rra_lib_arch_name=lib32], - [AS_IF([test "$ac_cv_sizeof_long" -eq 8 && test -d /usr/lib64], - [rra_lib_arch_name=lib64])])]) + AS_IF([test "$ac_cv_sizeof_long" -eq 4], + [rra_lib_arch_name=lib32], + [AS_IF([test "$ac_cv_sizeof_long" -eq 8], + [rra_lib_arch_name=lib64])])]) dnl Set VARIABLE to -LPREFIX/lib{,32,64} or -LPREFIX/lib{,32,64}/SUFFIX as dnl appropriate. @@ -53,11 +53,4 @@ AC_DEFUN([RRA_SET_LDFLAGS], [AS_IF([test x"$3" = x], [$1="[$]$1 -L$2/lib"], [$1="[$]$1 -L$2/lib/$3"])]) - $1=`echo "[$]$1" | sed -e 's/^ *//'`]) - -dnl Set libdir to PREFIX/lib{,32,64} as appropriate. -AC_DEFUN([RRA_SET_LIBDIR], -[AC_REQUIRE([_RRA_LIB_ARCH_NAME]) - AS_IF([test -d "$1/$rra_lib_arch_name"], - [libdir="$1/${rra_lib_arch_name}"], - [libdir="$1/lib"])]) + $1=`AS_ECHO(["[$]$1"]) | sed -e 's/^ *//'`]) diff --git a/m4/snprintf.m4 b/m4/snprintf.m4 deleted file mode 100644 index e739bbf..0000000 --- a/m4/snprintf.m4 +++ /dev/null @@ -1,62 +0,0 @@ -dnl Test for a working C99 snprintf. -dnl -dnl Check for a working snprintf. Some systems have an snprintf that doesn't -dnl nul-terminate if the buffer isn't large enough. Others return -1 if the -dnl string doesn't fit into the buffer instead of returning the number of -dnl characters that would have been formatted. Still others don't support -dnl NULL as the buffer argument (just to get a count of the formatted length). -dnl -dnl Provides RRA_FUNC_SNPRINTF, which adds snprintf.o to LIBOBJS unless a -dnl fully working snprintf is found. -dnl -dnl The canonical version of this file is maintained in the rra-c-util -dnl package, available at . -dnl -dnl Written by Russ Allbery -dnl Copyright 2006, 2008-2009 -dnl The Board of Trustees of the Leland Stanford Junior University -dnl -dnl This file is free software; the authors give unlimited permission to copy -dnl and/or distribute it, with or without modifications, as long as this -dnl notice is preserved. -dnl -dnl SPDX-License-Identifier: FSFULLR - -dnl Source used by RRA_FUNC_SNPRINTF. -AC_DEFUN([_RRA_FUNC_SNPRINTF_SOURCE], [[ -#include -#include - -char buf[2]; - -int -test(char *format, ...) -{ - va_list args; - int count; - - va_start(args, format); - count = vsnprintf(buf, sizeof buf, format, args); - va_end(args); - return count; -} - -int -main() -{ - return ((test("%s", "abcd") == 4 && buf[0] == 'a' && buf[1] == '\0' - && snprintf(NULL, 0, "%s", "abcd") == 4) ? 0 : 1); -} -]]) - -dnl The user-callable test. -AC_DEFUN([RRA_FUNC_SNPRINTF], -[AC_CACHE_CHECK([for working snprintf], [rra_cv_func_snprintf_works], - [AC_RUN_IFELSE([AC_LANG_SOURCE([_RRA_FUNC_SNPRINTF_SOURCE])], - [rra_cv_func_snprintf_works=yes], - [rra_cv_func_snprintf_works=no], - [rra_cv_func_snprintf_works=no])]) - AS_IF([test x"$rra_cv_func_snprintf_works" = xyes], - [AC_DEFINE([HAVE_SNPRINTF], 1, - [Define if your system has a working snprintf function.])], - [AC_LIBOBJ([snprintf])])]) diff --git a/m4/sqlite.m4 b/m4/sqlite.m4 deleted file mode 100644 index b0a7bd5..0000000 --- a/m4/sqlite.m4 +++ /dev/null @@ -1,80 +0,0 @@ -dnl Find the compiler and linker flags for SQLite. -dnl -dnl Finds the compiler and linker flags for linking with the SQLite library. -dnl Provides the --with-sqlite, --with-sqlite-lib, and --with-sqlite-include -dnl configure options to specify non-standard paths to the SQLite libraries or -dnl header files. Currently, only SQLite 3 is considered sufficient. -dnl -dnl Provides the macros RRA_LIB_SQLITE and RRA_LIB_SQLITE_OPTIONAL and sets -dnl the substitution variables SQLITE_CPPFLAGS, SQLITE_LDFLAGS, and -dnl SQLITE_LIBS. Also provides RRA_LIB_SQLITE_SWITCH to set CPPFLAGS, -dnl LDFLAGS, and LIBS to include the SQLite libraries, saving the current -dnl values first, and RRA_LIB_SQLITE_RESTORE to restore those settings to -dnl before the last RRA_LIB_SQLITE_SWITCH. Defines HAVE_SQLITE and sets -dnl rra_use_SQLITE to true if libevent is found. If it isn't found, the -dnl substitution variables will be empty. -dnl -dnl Depends on the lib-helper.m4 framework. -dnl -dnl The canonical version of this file is maintained in the rra-c-util -dnl package, available at . -dnl -dnl Written by Russ Allbery -dnl Copyright 2014 -dnl The Board of Trustees of the Leland Stanford Junior University -dnl -dnl This file is free software; the authors give unlimited permission to copy -dnl and/or distribute it, with or without modifications, as long as this -dnl notice is preserved. -dnl -dnl SPDX-License-Identifier: FSFULLR - -dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to -dnl versions that include the libevent flags. Used as a wrapper, with -dnl RRA_LIB_SQLITE_RESTORE, around tests. -AC_DEFUN([RRA_LIB_SQLITE_SWITCH], [RRA_LIB_HELPER_SWITCH([SQLITE])]) - -dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values before -dnl RRA_LIB_SQLITE_SWITCH was called. -AC_DEFUN([RRA_LIB_SQLITE_RESTORE], [RRA_LIB_HELPER_RESTORE([SQLITE])]) - -dnl Checks if SQLite is present. The single argument, if "true", says to fail -dnl if the SQLite library could not be found. Prefer probing with pkg-config -dnl if available and the --with flags were not given. -AC_DEFUN([_RRA_LIB_SQLITE_INTERNAL], -[RRA_LIB_HELPER_PATHS([SQLITE]) - AS_IF([test x"$SQLITE_CPPFLAGS" = x && test x"$SQLITE_LDFLAGS" = x], - [PKG_CHECK_EXISTS([sqlite3], - [PKG_CHECK_MODULES([SQLITE], [sqlite3]) - SQLITE_CPPFLAGS="$SQLITE_CFLAGS"])]) - AS_IF([test x"$SQLITE_LIBS" = x], - [RRA_LIB_SQLITE_SWITCH - LIBS= - AC_SEARCH_LIBS([sqlite3_open_v2], [sqlite3], - [SQLITE_LIBS="$LIBS"], - [AS_IF([test x"$1" = xtrue], - [AC_MSG_ERROR([cannot find usable SQLite library])])]) - RRA_LIB_SQLITE_RESTORE]) - RRA_LIB_SQLITE_SWITCH - AC_CHECK_HEADERS([sqlite3.h]) - RRA_LIB_SQLITE_RESTORE]) - -dnl The main macro for packages with mandatory SQLite 3 support. -AC_DEFUN([RRA_LIB_SQLITE], -[RRA_LIB_HELPER_VAR_INIT([SQLITE]) - RRA_LIB_HELPER_WITH([sqlite], [SQLite], [SQLITE]) - _RRA_LIB_SQLITE_INTERNAL([true]) - rra_use_SQLITE=true - AC_DEFINE([HAVE_SQLITE], 1, [Define if SQLite is available.])]) - -dnl The main macro for packages with optional SQLite support. -AC_DEFUN([RRA_LIB_SQLITE_OPTIONAL], -[RRA_LIB_HELPER_VAR_INIT([SQLITE]) - RRA_LIB_HELPER_WITH_OPTIONAL([sqlite], [SQLite], [SQLITE]) - AS_IF([test x"$rra_use_SQLITE" != xfalse], - [AS_IF([test x"$rra_use_SQLITE" = xtrue], - [_RRA_LIB_SQLITE_INTERNAL([true])], - [_RRA_LIB_SQLITE_INTERNAL([false])])]) - AS_IF([test x"$SQLITE_LIBS" != x], - [rra_use_SQLITE=true - AC_DEFINE([HAVE_SQLITE], 1, [Define if SQLite is available.])])]) diff --git a/m4/sqlite3.m4 b/m4/sqlite3.m4 new file mode 100644 index 0000000..597a612 --- /dev/null +++ b/m4/sqlite3.m4 @@ -0,0 +1,91 @@ +# serial 1 + +dnl Find the compiler and linker flags for SQLite v3. +dnl +dnl Finds the compiler and linker flags for linking with the SQLite library. +dnl Provides the --with-sqlite3, --with-sqlite3-lib, and +dnl --with-sqlite3-include configure options to specify non-standard paths to +dnl the SQLite v3 libraries or header files. +dnl +dnl Provides the macro RRA_LIB_SQLITE3 and sets the substitution variables +dnl SQLITE3_CPPFLAGS, SQLITE3_LDFLAGS, and SQLITE3_LIBS. Also provides +dnl RRA_LIB_SQLITE3_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the +dnl SQLite library, saving the current values first, and +dnl RRA_LIB_SQLITE3_RESTORE to restore those settings to before the last +dnl RRA_LIB_SQLITE3_SWITCH. Defines HAVE_SQLITE3 and sets rra_use_SQLITE3 to +dnl true. +dnl +dnl Provides the RRA_LIB_SQLITE3_OPTIONAL macro, which should be used if +dnl SQLite support is optional. This macro will still always set the +dnl substitution variables, but they'll be empty if the SQLite library is not +dnl found or if --without-sqlite3 is given. Defines HAVE_SQLITE3 and sets +dnl rra_use_SQLITE3 to true if the SQLite library is found and +dnl --without-sqlite3 is not given. +dnl +dnl Depends on the lib-helper.m4 framework and the Autoconf macros that come +dnl with pkg-config. +dnl +dnl The canonical version of this file is maintained in the rra-c-util +dnl package, available at . +dnl +dnl Written by Russ Allbery +dnl Copyright 2020, 2022 Russ Allbery +dnl Copyright 2014 +dnl The Board of Trustees of the Leland Stanford Junior University +dnl +dnl This file is free software; the authors give unlimited permission to copy +dnl and/or distribute it, with or without modifications, as long as this +dnl notice is preserved. +dnl +dnl SPDX-License-Identifier: FSFULLR + +dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to +dnl versions that include the SQLite 3 flags. Used as a wrapper, with +dnl RRA_LIB_SQLITE3_RESTORE, around tests. +AC_DEFUN([RRA_LIB_SQLITE3_SWITCH], [RRA_LIB_HELPER_SWITCH([SQLITE3])]) + +dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values before +dnl RRA_LIB_SQLITE3_SWITCH was called. +AC_DEFUN([RRA_LIB_SQLITE3_RESTORE], [RRA_LIB_HELPER_RESTORE([SQLITE3])]) + +dnl Checks if SQLite v3 is present. The single argument, if "true", says to +dnl fail if the SQLite library could not be found. Prefer probing with +dnl pkg-config if available and the --with flags were not given. +AC_DEFUN([_RRA_LIB_SQLITE3_INTERNAL], +[RRA_LIB_HELPER_PATHS([SQLITE3]) + AS_IF([test x"$SQLITE3_CPPFLAGS" = x && test x"$SQLITE3_LDFLAGS" = x], + [PKG_CHECK_EXISTS([sqlite3], + [PKG_CHECK_MODULES([SQLITE3], [sqlite3]) + SQLITE3_CPPFLAGS="$SQLITE3_CFLAGS"])]) + AS_IF([test x"$SQLITE3_LIBS" = x], + [RRA_LIB_SQLITE3_SWITCH + LIBS= + AC_SEARCH_LIBS([sqlite3_open_v2], [sqlite3], + [SQLITE3_LIBS="$LIBS"], + [AS_IF([test x"$1" = xtrue], + [AC_MSG_ERROR([cannot find usable libsqlite3 library])])]) + RRA_LIB_SQLITE3_RESTORE]) + RRA_LIB_SQLITE3_SWITCH + AC_CHECK_HEADERS([sqlite3.h]) + RRA_LIB_SQLITE3_RESTORE]) + +dnl The main macro for packages with mandatory SQLite v3 support. +AC_DEFUN([RRA_LIB_SQLITE3], +[RRA_LIB_HELPER_VAR_INIT([SQLITE3]) + RRA_LIB_HELPER_WITH([sqlite3], [SQLite v3], [SQLITE3]) + _RRA_LIB_SQLITE3_INTERNAL([true]) + rra_use_SQLITE3=true + AC_DEFINE([HAVE_SQLITE3], 1, [Define if libsqlite3 is available.])]) + +dnl The main macro for packages with optional SQLite v3 support. +AC_DEFUN([RRA_LIB_SQLITE3_OPTIONAL], +[RRA_LIB_HELPER_VAR_INIT([SQLITE3]) + RRA_LIB_HELPER_WITH_OPTIONAL([sqlite3], [SQLite v3], [SQLITE3]) + AS_IF([test x"$rra_use_SQLITE3" != xfalse], + [AS_IF([test x"$rra_use_SQLITE3" = xtrue], + [_RRA_LIB_SQLITE3_INTERNAL([true])], + [_RRA_LIB_SQLITE3_INTERNAL([false])])]) + AS_IF([test x"$SQLITE3_LIBS" = x], + [RRA_LIB_HELPER_VAR_CLEAR([SQLITE3])], + [rra_use_SQLITE3=true + AC_DEFINE([HAVE_SQLITE3], 1, [Define if libsqlite3 is available.])])]) diff --git a/m4/tinycdb.m4 b/m4/tinycdb.m4 index 8aff1e3..ccb15d6 100644 --- a/m4/tinycdb.m4 +++ b/m4/tinycdb.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Find the compiler and linker flags for libcdb. dnl dnl Finds the compiler and linker flags for linking with the libcdb library. diff --git a/m4/vamacros.m4 b/m4/vamacros.m4 index 5595b86..2dde147 100644 --- a/m4/vamacros.m4 +++ b/m4/vamacros.m4 @@ -1,3 +1,5 @@ +# serial 1 + dnl Check for support for variadic macros. dnl dnl This file defines two macros for probing for compiler support for variadic diff --git a/plugin/cracklib.c b/plugin/cracklib.c index f6a1b23..d6e56f8 100644 --- a/plugin/cracklib.c +++ b/plugin/cracklib.c @@ -5,10 +5,9 @@ * CrackLib library, including initialization and checking of a password * against a CrackLib dictionary. * - * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine Associates, - * on behalf of Stanford University - * Extensive modifications by Russ Allbery - * Copyright 2017 Russ Allbery + * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine + * Associates, on behalf of Stanford University Extensive modifications by Russ + * Allbery Copyright 2017 Russ Allbery * Copyright 2006-2007, 2009, 2012-2013 * The Board of Trustees of the Leland Stanford Junior University * diff --git a/plugin/general.c b/plugin/general.c index 4f8b0cf..325f785 100644 --- a/plugin/general.c +++ b/plugin/general.c @@ -6,11 +6,10 @@ * are called by the implementation-specific code, and all other checks are * wrapped up in those interfaces. * - * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine Associates, - * on behalf of Stanford University - * Extensive modifications by Russ Allbery - * Copyright 2006-2007, 2009, 2012-2014 - * The Board of Trustees of the Leland Stanford Junior University + * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine + * Associates, on behalf of Stanford University Extensive modifications by Russ + * Allbery Copyright 2006-2007, 2009, 2012-2014 The Board of + * Trustees of the Leland Stanford Junior University * * SPDX-License-Identifier: MIT */ diff --git a/plugin/internal.h b/plugin/internal.h index dbd99fe..ab68bfd 100644 --- a/plugin/internal.h +++ b/plugin/internal.h @@ -1,9 +1,10 @@ /* * Prototypes for the kadmin password strength checking plugin. * - * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine Associates, - * on behalf of Stanford University + * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine + * Associates, on behalf of Stanford University * Extensive modifications by Russ Allbery + * Copyright 2023 Russ Allbery * Copyright 2006-2007, 2009, 2012-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -163,7 +164,7 @@ krb5_error_code strength_check_cracklib(krb5_context, krb5_pwqual_moddata, * requested and not available. */ krb5_error_code strength_init_sqlite(krb5_context, krb5_pwqual_moddata); -#ifdef HAVE_SQLITE +#ifdef HAVE_SQLITE3 krb5_error_code strength_check_sqlite(krb5_context, krb5_pwqual_moddata, const char *password); void strength_close_sqlite(krb5_context, krb5_pwqual_moddata); diff --git a/plugin/principal.c b/plugin/principal.c index 9fc6e9b..cd3b8b8 100644 --- a/plugin/principal.c +++ b/plugin/principal.c @@ -5,10 +5,9 @@ * password is being changed, trying to detect and reject passwords based on * components of the principal. * - * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine Associates, - * on behalf of Stanford University - * Extensive modifications by Russ Allbery - * Copyright 2020 Russ Allbery + * Developed by Daria Phoebe Brashear and Ken Hornstein of Sine Nomine + * Associates, on behalf of Stanford University Extensive modifications by Russ + * Allbery Copyright 2020 Russ Allbery * Copyright 2006-2007, 2009, 2012-2014 * The Board of Trustees of the Leland Stanford Junior University * diff --git a/plugin/sqlite.c b/plugin/sqlite.c index fc91e5b..db73aef 100644 --- a/plugin/sqlite.c +++ b/plugin/sqlite.c @@ -29,7 +29,7 @@ * * Written by Russ Allbery * Based on work by David Mazières - * Copyright 2016, 2020 Russ Allbery + * Copyright 2016, 2020, 2023 Russ Allbery * Copyright 2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -65,7 +65,7 @@ /* * Stub for strength_init_sqlite if not built with SQLite support. */ -#ifndef HAVE_SQLITE +#ifndef HAVE_SQLITE3 krb5_error_code strength_init_sqlite(krb5_context ctx, krb5_pwqual_moddata data UNUSED) { @@ -87,7 +87,7 @@ strength_init_sqlite(krb5_context ctx, krb5_pwqual_moddata data UNUSED) /* Skip the rest of this file if SQLite is not available. */ -#ifdef HAVE_SQLITE +#ifdef HAVE_SQLITE3 /* * Report a SQLite error. Takes the module data (used to access the SQLite @@ -402,4 +402,4 @@ strength_close_sqlite(krb5_context ctx UNUSED, krb5_pwqual_moddata data) sqlite3_close(data->sqlite); } -#endif /* HAVE_SQLITE */ +#endif /* HAVE_SQLITE3 */ diff --git a/plugin/vector.c b/plugin/vector.c index 9c43207..dca341e 100644 --- a/plugin/vector.c +++ b/plugin/vector.c @@ -206,7 +206,7 @@ strength_vector_split_multi(const char *string, const char *seps, for (start = string, p = string, i = 0; *p != '\0'; p++) if (strchr(seps, *p) != NULL) { if (start != p) { - vector->strings[i] = strndup(start, (size_t)(p - start)); + vector->strings[i] = strndup(start, (size_t) (p - start)); if (vector->strings[i] == NULL) goto fail; i++; @@ -217,7 +217,7 @@ strength_vector_split_multi(const char *string, const char *seps, /* If there is anything left in the string, we have one more component. */ if (start != p) { - vector->strings[i] = strndup(start, (size_t)(p - start)); + vector->strings[i] = strndup(start, (size_t) (p - start)); if (vector->strings[i] == NULL) goto fail; vector->count++; diff --git a/portable/macros.h b/portable/macros.h index 5d77fb7..cf4c4a2 100644 --- a/portable/macros.h +++ b/portable/macros.h @@ -5,7 +5,7 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2015 Russ Allbery + * Copyright 2015, 2022 Russ Allbery * Copyright 2008, 2011-2012 * The Board of Trustees of the Leland Stanford Junior University * @@ -45,6 +45,16 @@ # endif #endif +/* + * Suppress the argument to __malloc__ in Clang (not supported in at least + * version 13) and GCC versions prior to 11. + */ +#if !defined(__attribute__) && !defined(__malloc__) +# if defined(__clang__) || __GNUC__ < 11 +# define __malloc__(dalloc) __malloc__ +# endif +#endif + /* * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ * settings that GCC does. For them, suppress warnings about unknown diff --git a/portable/snprintf.c b/portable/snprintf.c deleted file mode 100644 index a22e4e4..0000000 --- a/portable/snprintf.c +++ /dev/null @@ -1,992 +0,0 @@ -/* - * Replacement for a missing snprintf or vsnprintf. - * - * The following implementation of snprintf was taken mostly verbatim from - * ; it is the version of snprintf - * used in Mutt. A possibly newer version is used in wget, found at - * . - * - * Please do not reformat or otherwise change this file more than necessary so - * that later merges with the original source are easy. Bug fixes and - * improvements should be sent back to the original author. - * - * The canonical version of this file is maintained in the rra-c-util package, - * which can be found at . - */ - -/* - * If we're running the test suite, rename snprintf and vsnprintf to avoid - * conflicts with the system version. - */ -#if TESTING -# undef snprintf -# undef vsnprintf -# define snprintf test_snprintf -# define vsnprintf test_vsnprintf -#endif - -/* - * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 - * could you use the __format__ form of the attributes, which is what we use - * (to avoid confusion with other macros). - */ -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __attribute__(spec) /* empty */ -# endif -#endif - -/* - * Older Clang doesn't support __attribute__((fallthrough)) properly and - * complains about the empty statement that it is decorating. Suppress that - * warning. Also suppress warnings about unknown attributes to handle older - * Clang versions. - */ -#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) -# pragma GCC diagnostic ignored "-Wattributes" -# pragma GCC diagnostic ignored "-Wmissing-declarations" -#endif - -/* Specific to rra-c-util, but only when debugging is enabled. */ -#ifdef DEBUG_SNPRINTF -# include -#endif - -/* - * Copyright Patrick Powell 1995 - * This code is based on code written by Patrick Powell (papowell@astart.com) - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions - * - * There is no SPDX-License-Identifier registered for this license. - */ - -/************************************************************** - * Original: - * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 - * A bombproof version of doprnt (dopr) included. - * Sigh. This sort of thing is always nasty do deal with. Note that - * the version here does not include floating point... - * - * snprintf() is used instead of sprintf() as it does limit checks - * for string length. This covers a nasty loophole. - * - * The other functions are there to prevent NULL pointers from - * causing nast effects. - * - * More Recently: - * Brandon Long 9/15/96 for mutt 0.43 - * This was ugly. It is still ugly. I opted out of floating point - * numbers, but the formatter understands just about everything - * from the normal C string format, at least as far as I can tell from - * the Solaris 2.5 printf(3S) man page. - * - * Brandon Long 10/22/97 for mutt 0.87.1 - * Ok, added some minimal floating point support, which means this - * probably requires libm on most operating systems. Don't yet - * support the exponent (e,E) and sigfig (g,G). Also, fmtint() - * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formatted the code - * to mutt conventions, and removed dead code left over from the - * original. Also, there is now a builtin-test, just compile with: - * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm - * and run snprintf for results. - * - * Thomas Roessler 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. - * - * Michael Elkins 03/05/98 for mutt 0.90.8 - * The original code assumed that both snprintf() and vsnprintf() were - * missing. Some systems only have snprintf() but not vsnprintf(), so - * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. - * - * Andrew Tridgell (tridge@samba.org) Oct 1998 - * fixed handling of %.0f - * added test for HAVE_LONG_DOUBLE - * - * Russ Allbery 2000-08-26 - * fixed return value to comply with C99 - * fixed handling of snprintf(NULL, ...) - * added explicit casts for double to long long int conversion - * fixed various warnings with GCC 7 - * fixed various warnings with Clang - * - * Hrvoje Niksic 2000-11-04 - * include instead of "config.h". - * moved TEST_SNPRINTF stuff out of HAVE_SNPRINTF ifdef. - * include for NULL. - * added support and test cases for long long. - * don't declare argument types to (v)snprintf if stdarg is not used. - * use int instead of short int as 2nd arg to va_arg. - * - * alexk (INN) 2002-08-21 - * use LLONG in fmtfp to handle more characters during floating - * point conversion. - * - * herb (Samba) 2002-12-19 - * actually print args for %g and %e - * - * Hrvoje Niksic 2005-04-15 - * use the PARAMS macro to handle prototypes. - * write function definitions in the ansi2knr-friendly way. - * if string precision is specified, don't read VALUE past it. - * fix bug in fmtfp that caused 0.01 to be printed as 0.1. - * don't include because none of it is used. - * interpret precision as number of significant digits with %g - * omit trailing decimal zeros with %g - * - **************************************************************/ - -#include - -#include -#include -#include - -#ifndef NULL -# define NULL 0 -#endif - -/* varargs declarations: */ - -#include - -/* Assume all compilers support long double, per Autoconf documentation. */ -#define LDOUBLE long double - -#ifdef HAVE_LONG_LONG_INT -# define LLONG long long -#else -# define LLONG long -#endif - -int snprintf (char *str, size_t count, const char *fmt, ...); -int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); - -static int dopr (char *buffer, size_t maxlen, const char *format, - va_list args); -static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, - const char *value, int flags, int min, int max); -static int fmtint (char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags); -static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags); -static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); - -/* - * dopr(): poor man's version of doprintf - */ - -/* format read states */ -#define DP_S_DEFAULT 0 -#define DP_S_FLAGS 1 -#define DP_S_MIN 2 -#define DP_S_DOT 3 -#define DP_S_MAX 4 -#define DP_S_MOD 5 -#define DP_S_MOD_L 6 -#define DP_S_CONV 7 -#define DP_S_DONE 8 - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UP (1 << 5) -#define DP_F_UNSIGNED (1 << 6) -#define DP_F_FP_G (1 << 7) - -/* Conversion Flags */ -#define DP_C_SHORT 1 -#define DP_C_LONG 2 -#define DP_C_LLONG 3 -#define DP_C_LDOUBLE 4 - -#define char_to_int(p) (p - '0') -#define MAX(p,q) ((p >= q) ? p : q) -#define MIN(p,q) ((p <= q) ? p : q) - -static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) -{ - char ch; - LLONG value; - LDOUBLE fvalue; - char *strvalue; - int min; - int max; - unsigned int state; - int flags; - int cflags; - int total; - size_t currlen; - - state = DP_S_DEFAULT; - currlen = flags = cflags = min = 0; - max = -1; - ch = *format++; - total = 0; - - while (state != DP_S_DONE) - { - if (ch == '\0') - state = DP_S_DONE; - - switch(state) - { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - total += dopr_outch (buffer, &currlen, maxlen, ch); - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) - { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if ('0' <= ch && ch <= '9') - { - min = 10*min + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } - else - state = DP_S_DOT; - break; - case DP_S_DOT: - if (ch == '.') - { - state = DP_S_MAX; - ch = *format++; - } - else - state = DP_S_MOD; - break; - case DP_S_MAX: - if ('0' <= ch && ch <= '9') - { - if (max < 0) - max = 0; - max = 10*max + char_to_int (ch); - ch = *format++; - } - else if (ch == '*') - { - max = va_arg (args, int); - ch = *format++; - state = DP_S_MOD; - } - else - state = DP_S_MOD; - break; - case DP_S_MOD: - switch (ch) - { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - if (cflags != DP_C_LONG) - state = DP_S_CONV; - else - state = DP_S_MOD_L; - break; - case DP_S_MOD_L: - switch (ch) - { - case 'l': - cflags = DP_C_LLONG; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) - { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = (short int) va_arg (args, int); - else if (cflags == DP_C_LONG) - value = va_arg (args, long int); - else if (cflags == DP_C_LLONG) - value = va_arg (args, LLONG); - else - value = va_arg (args, int); - total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'o': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = (unsigned short int) va_arg (args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = va_arg (args, unsigned LLONG); - else - value = va_arg (args, unsigned int); - total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = (unsigned short int) va_arg (args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = va_arg (args, unsigned LLONG); - else - value = va_arg (args, unsigned int); - total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - __attribute__((fallthrough)); - /* fall through */ - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = (unsigned short int) va_arg (args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg (args, unsigned long int); - else if (cflags == DP_C_LLONG) - value = va_arg (args, unsigned LLONG); - else - value = va_arg (args, unsigned int); - total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = (LDOUBLE) va_arg (args, double); - total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'E': - flags |= DP_F_UP; - __attribute__((fallthrough)); - /* fall through */ - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = (LDOUBLE) va_arg (args, double); - total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'G': - flags |= DP_F_UP; - __attribute__((fallthrough)); - /* fall through */ - case 'g': - flags |= DP_F_FP_G; - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg (args, LDOUBLE); - else - fvalue = (LDOUBLE) va_arg (args, double); - if (max == 0) - /* C99 says: if precision [for %g] is zero, it is taken as one */ - max = 1; - total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'c': - total += dopr_outch (buffer, &currlen, maxlen, - (char) va_arg (args, int)); - break; - case 's': - strvalue = va_arg (args, char *); - total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); - break; - case 'p': - strvalue = va_arg (args, void *); - total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, - max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) - { - short int *num; - num = va_arg (args, short int *); - *num = (short) currlen; - } - else if (cflags == DP_C_LONG) - { - long int *num; - num = va_arg (args, long int *); - *num = currlen; - } - else if (cflags == DP_C_LLONG) - { - LLONG *num; - num = va_arg (args, LLONG *); - *num = currlen; - } - else - { - int *num; - num = va_arg (args, int *); - *num = (int) currlen; - } - break; - case '%': - total += dopr_outch (buffer, &currlen, maxlen, ch); - break; - case 'w': - /* not supported yet, treat as next char */ - format++; - break; - default: - /* Unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - if (buffer != NULL) - { - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; - } - return total; -} - -static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, - const char *value, int flags, int min, int max) -{ - int padlen, strln; /* amount to pad */ - int cnt = 0; - int total = 0; - - if (value == 0) - { - value = "(null)"; - } - - if (max < 0) - strln = (int) strlen (value); - else - /* When precision is specified, don't read VALUE past precision. */ - /*strln = strnlen (value, max);*/ - for (strln = 0; strln < max && value[strln]; ++strln); - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while (padlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - while (*value && ((max < 0) || (cnt < max))) - { - total += dopr_outch (buffer, currlen, maxlen, *value++); - ++cnt; - } - while (padlen < 0) - { - total += dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } - return total; -} - -/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ - -static int fmtint (char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags) -{ - char signvalue = 0; - unsigned LLONG uvalue; - char convert[24]; - unsigned int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - const char *digits; - int total = 0; - - if (max < 0) - max = 0; - - uvalue = value; - - if(!(flags & DP_F_UNSIGNED)) - { - if( value < 0 ) { - signvalue = '-'; - uvalue = -value; - } - else - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; - } - - if (flags & DP_F_UP) - /* Should characters be upper case? */ - digits = "0123456789ABCDEF"; - else - digits = "0123456789abcdef"; - - do { - convert[place++] = digits[uvalue % (unsigned)base]; - uvalue = (uvalue / (unsigned)base ); - } while(uvalue && (place < sizeof (convert))); - if (place == sizeof (convert)) place--; - convert[place] = 0; - - zpadlen = max - place; - spadlen = min - MAX ((unsigned int)max, place) - (signvalue ? 1 : 0); - if (zpadlen < 0) zpadlen = 0; - if (spadlen < 0) spadlen = 0; - if (flags & DP_F_ZERO) - { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - -#ifdef DEBUG_SNPRINTF - debug ("zpad: %d, spad: %d, min: %d, max: %d, place: %u\n", - zpadlen, spadlen, min, max, place); -#endif - - /* Spaces */ - while (spadlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - total += dopr_outch (buffer, currlen, maxlen, signvalue); - - /* Zeros */ - if (zpadlen > 0) - { - while (zpadlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - } - - /* Digits */ - while (place > 0) - total += dopr_outch (buffer, currlen, maxlen, convert[--place]); - - /* Left Justified spaces */ - while (spadlen < 0) { - total += dopr_outch (buffer, currlen, maxlen, ' '); - ++spadlen; - } - - return total; -} - -static LDOUBLE abs_val (LDOUBLE value) -{ - LDOUBLE result = value; - - if (value < 0) - result = -value; - - return result; -} - -static LLONG pow10_int (unsigned int exp) -{ - LDOUBLE result = 1; - - while (exp) - { - result *= 10; - exp--; - } - - return (LLONG) result; -} - -static LLONG round_int (LDOUBLE value) -{ - LLONG intpart; - - intpart = (LLONG) value; - value = value - intpart; - if (value >= (LDOUBLE) 0.5) - intpart++; - - return intpart; -} - -/* - * GCC 7.1 issues this warning at the point of the function definition header - * (not in any actual code), and I can't figure out what's triggering it since - * the comparison form doesn't appear anywhere in this code. Since this is - * rarely-used portability code, suppress the warning. - */ -#pragma GCC diagnostic ignored "-Wstrict-overflow" - -static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags) -{ - char signvalue = 0; - LDOUBLE ufvalue; - char iconvert[24]; - char fconvert[24]; - size_t iplace = 0; - size_t fplace = 0; - long padlen = 0; /* amount to pad */ - long zpadlen = 0; - int total = 0; - LLONG intpart; - LLONG fracpart; - LLONG mask10; - int leadingfrac0s = 0; /* zeroes at the start of fractional part */ - int omitzeros = 0; - size_t omitcount = 0; - - /* - * AIX manpage says the default is 0, but Solaris says the default - * is 6, and sprintf on AIX defaults to 6 - */ - if (max < 0) - max = 6; - - ufvalue = abs_val (fvalue); - - if (fvalue < 0) - signvalue = '-'; - else - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else - if (flags & DP_F_SPACE) - signvalue = ' '; - -#if 0 - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ -#endif - - intpart = (LLONG) ufvalue; - - /* With %g precision is the number of significant digits, which - includes the digits in intpart. */ - if (flags & DP_F_FP_G) - { - if (intpart != 0) - { - /* For each digit of INTPART, print one less fractional digit. */ - LLONG temp; - for (temp = intpart; temp != 0; temp /= 10) - --max; - if (max < 0) - max = 0; - } - else - { - /* For each leading 0 in fractional part, print one more - fractional digit. */ - LDOUBLE temp; - if (ufvalue > 0) - for (temp = ufvalue; temp < (LDOUBLE) 0.1; temp *= 10) - ++max; - } - } - - /* C99: trailing zeros are removed from the fractional portion of the - result unless the # flag is specified */ - if ((flags & DP_F_FP_G) && !(flags & DP_F_NUM)) - omitzeros = 1; - -#if SIZEOF_LONG_LONG > 0 -# define MAX_DIGITS 18 /* grok more digits with long long */ -#else -# define MAX_DIGITS 9 /* just long */ -#endif - - /* - * Sorry, we only support several digits past the decimal because of - * our conversion method - */ - if (max > MAX_DIGITS) - max = MAX_DIGITS; - - /* Factor of 10 with the needed number of digits, e.g. 1000 for max==3 */ - mask10 = pow10_int (max); - - /* We "cheat" by converting the fractional part to integer by - * multiplying by a factor of 10 - */ - fracpart = round_int (mask10 * (ufvalue - intpart)); - - if (fracpart >= mask10) - { - intpart++; - fracpart -= mask10; - } - else if (fracpart != 0) - /* If fracpart has less digits than the 10* mask, we need to - manually insert leading 0s. For example 2.01's fractional part - requires one leading zero to distinguish it from 2.1. */ - while (fracpart < mask10 / 10) - { - ++leadingfrac0s; - mask10 /= 10; - } - -#ifdef DEBUG_SNPRINTF -# ifdef HAVE_LONG_LONG_INT - debug ("fmtfp: %Lf =? %lld.%lld\n", fvalue, intpart, fracpart); -# else - debug ("fmtfp: %Lf =? %ld.%ld\n", fvalue, intpart, fracpart); -# endif -#endif - - /* Convert integer part */ - do { - iconvert[iplace++] = (char) ('0' + (intpart % 10)); - intpart = (intpart / 10); - } while(intpart && (iplace < sizeof(iconvert))); - if (iplace == sizeof(iconvert)) iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - do { - fconvert[fplace++] = (char) ('0' + (fracpart % 10)); - fracpart = (fracpart / 10); - } while(fracpart && (fplace < sizeof(fconvert))); - while (leadingfrac0s-- > 0 && fplace < sizeof(fconvert)) - fconvert[fplace++] = '0'; - if (fplace == sizeof(fconvert)) fplace--; - fconvert[fplace] = 0; - if (omitzeros) - while (omitcount < fplace && fconvert[omitcount] == '0') - ++omitcount; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - (max - omitcount) - 1 - ((signvalue) ? 1 : 0); - if (!omitzeros) - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) - { - if (signvalue) - { - total += dopr_outch (buffer, currlen, maxlen, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, '0'); - --padlen; - } - } - while (padlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - if (signvalue) - total += dopr_outch (buffer, currlen, maxlen, signvalue); - - while (iplace > 0) - total += dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0 && (fplace > omitcount || zpadlen > 0)) - { - total += dopr_outch (buffer, currlen, maxlen, '.'); - - while (fplace > omitcount) - total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - } - - while (zpadlen > 0) - { - total += dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (padlen < 0) - { - total += dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } - - return total; -} - -static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) -{ - if (*currlen + 1 < maxlen) - buffer[(*currlen)++] = c; - return 1; -} - -int vsnprintf (char *str, size_t count, const char *fmt, va_list args) -{ - if (str != NULL) - str[0] = 0; - return dopr(str, count, fmt, args); -} - -int snprintf (char *str, size_t count, const char *fmt,...) -{ - va_list ap; - int total; - - va_start(ap, fmt); - total = vsnprintf(str, count, fmt, ap); - va_end(ap); - return total; -} - -#ifdef TEST_SNPRINTF -#ifndef LONG_STRING -#define LONG_STRING 1024 -#endif -int main (void) -{ - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%.1f", - NULL - }; - double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 0}; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - NULL - }; - long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; - int x, y; - int fail = 0; - int num = 0; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) - for (y = 0; fp_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - - for (x = 0; int_fmt[x] != NULL ; x++) - for (y = 0; int_nums[y] != 0 ; y++) - { - snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf (buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) - { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - printf ("%d tests failed out of %d.\n", fail, num); - return 0; -} -#endif /* TEST_SNPRINTF */ diff --git a/portable/stdbool.h b/portable/stdbool.h index 749052a..f670bf4 100644 --- a/portable/stdbool.h +++ b/portable/stdbool.h @@ -47,8 +47,8 @@ typedef unsigned char _Bool; # define bool _Bool # endif # endif -# define false 0 -# define true 1 +# define false 0 +# define true 1 # define __bool_true_false_are_defined 1 #endif diff --git a/portable/strndup.c b/portable/strndup.c index 9ddcbc1..c486ce0 100644 --- a/portable/strndup.c +++ b/portable/strndup.c @@ -44,7 +44,7 @@ strndup(const char *s, size_t n) } /* Don't assume that the source string is nul-terminated. */ - for (p = s; (size_t)(p - s) < n && *p != '\0'; p++) + for (p = s; (size_t) (p - s) < n && *p != '\0'; p++) ; length = p - s; copy = malloc(length + 1); diff --git a/portable/system.h b/portable/system.h index e98d564..2b78d20 100644 --- a/portable/system.h +++ b/portable/system.h @@ -10,9 +10,9 @@ * #include * #include * #include + * #include * #include * #include - * #include * #include * #include * #include @@ -25,7 +25,7 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2014, 2016, 2018, 2020 Russ Allbery + * Copyright 2014, 2016, 2018, 2020-2021 Russ Allbery * Copyright 2006-2011, 2013-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -75,6 +75,11 @@ /* Get the bool type. */ #include +/* In case uint32_t and associated limits weren't defined. */ +#ifndef UINT32_MAX +# define UINT32_MAX 4294967295UL +#endif + /* Windows provides snprintf under a different name. */ #ifdef _WIN32 # define snprintf _snprintf @@ -133,18 +138,10 @@ extern int asprintf(char **, const char *, ...) extern int vasprintf(char **, const char *, va_list) __attribute__((__format__(printf, 2, 0))); #endif -#if !HAVE_DECL_SNPRINTF -extern int snprintf(char *, size_t, const char *, ...) - __attribute__((__format__(printf, 3, 4))); -#endif -#if !HAVE_DECL_VSNPRINTF -extern int vsnprintf(char *, size_t, const char *, va_list) - __attribute__((__format__(printf, 3, 0))); -#endif #if !HAVE_MKSTEMP extern int mkstemp(char *); #endif -#if !HAVE_REALLOCARRAY +#if !HAVE_DECL_REALLOCARRAY extern void *reallocarray(void *, size_t, size_t); #endif #if !HAVE_STRNDUP diff --git a/tests/TESTS b/tests/TESTS index a596aa9..74eb064 100644 --- a/tests/TESTS +++ b/tests/TESTS @@ -1,7 +1,7 @@ # Test list for krb5-strength. -*- conf -*- # # Written by Russ Allbery -# Copyright 2016, 2020 Russ Allbery +# Copyright 2016, 2020, 2023 Russ Allbery # Copyright 2009-2010, 2013-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -22,7 +22,6 @@ perl/minimum-version perl/strict portable/asprintf valgrind portable/mkstemp valgrind -portable/snprintf valgrind portable/strndup valgrind style/obsolete-strings tools/heimdal-history diff --git a/tests/data/cppcheck.supp b/tests/data/cppcheck.supp index 442c431..c9f8ff1 100644 --- a/tests/data/cppcheck.supp +++ b/tests/data/cppcheck.supp @@ -8,7 +8,7 @@ // with the --xml flag and then add a suppression for the error id, file // location, and line. // -// Copyright 2018-2020 Russ Allbery +// Copyright 2018-2022 Russ Allbery // // Copying and distribution of this file, with or without modification, are // permitted in any medium without royalty provided the copyright notice and @@ -28,22 +28,34 @@ constArgument:tests/runtests.c:804 // False positive due to recursive function. knownConditionTrueFalse:portable/getopt.c:146 +// Bug in cppcheck 2.3. cppcheck can't see the assignment because of the +// void * cast. +knownConditionTrueFalse:portable/k_haspag.c:61 + // False positive since the string comes from a command-line define. +knownConditionTrueFalse:tests/tap/process.c:415 knownConditionTrueFalse:tests/tap/remctl.c:79 // Stored in the returned ai struct, but cppcheck can't see the assignment // because of the struct sockaddr * cast. memleak:portable/getaddrinfo.c:236 -// Bug in cppcheck 1.89. The address of this variable is passed to a Windows -// function (albeit through a cast). -nullPointer:portable/winsock.c:61 +// Bug in cppcheck 1.89 (fixed in 2.3). The address of this variable is +// passed to a Windows function (albeit through a cast). +nullPointer:portable/winsock.c:62 + +// Bug in cppcheck 2.3. +nullPointerRedundantCheck:portable/krb5-profile.c:61 + +// Bug in cppcheck 2.3. +nullPointerRedundantCheck:portable/krb5-renew.c:82 +nullPointerRedundantCheck:portable/krb5-renew.c:83 // Setting the variable to NULL explicitly after deallocation. redundantAssignment:tests/pam-util/options-t.c -// (remctl) Bug in cppcheck 1.89. The address of these variables are passed -// to a PHP function. +// (remctl) Bug in cppcheck 1.89 (fixed in 2.3). The address of these +// variables are passed to a PHP function. uninitvar:php/php_remctl.c:119 uninitvar:php/php_remctl.c:123 uninitvar:php/php_remctl.c:315 @@ -51,5 +63,15 @@ uninitvar:php/php5_remctl.c:125 uninitvar:php/php5_remctl.c:129 uninitvar:php/php5_remctl.c:321 +// (remctl) Bug in cppcheck 1.82. A pointer to this array is stored in a +// struct that's passed to another function. +redundantAssignment:tests/server/acl-t.c + // (pam-krb5) cppcheck doesn't recognize the unused attribute on labels. unusedLabel:module/auth.c:895 +unusedLabelConfiguration:module/auth.c:895 + +// Bug in cppcheck 2.7. Two possible struct layouts are chosen based on the +// ABI, and the one chosen is used, but cppcheck always warns about both even +// if the preprocessor conditionals are identical. +unusedStructMember:kafs/sys-solaris.c diff --git a/tests/data/passwords/make-c-data b/tests/data/passwords/make-c-data index d525c0a..1fd2c54 100755 --- a/tests/data/passwords/make-c-data +++ b/tests/data/passwords/make-c-data @@ -14,18 +14,18 @@ use strict; use warnings; use Carp qw(croak); +use Const::Fast qw(const); use Encode qw(encode); use File::Basename qw(basename); -use JSON; +use JSON::MaybeXS qw(JSON); use Perl6::Slurp qw(slurp); -use Readonly; ############################################################################## # Global variables ############################################################################## # The header on the generated source file. -Readonly my $HEADER => <<'END_HEADER'; +const my $HEADER => <<'END_HEADER'; /* * Automatically generated -- do not edit! * @@ -46,16 +46,16 @@ Readonly my $HEADER => <<'END_HEADER'; END_HEADER # The list of attributes, in order, whose values go into the C struct. -Readonly my @ATTRIBUTES => qw( - name principal password code error skip_for_system_cracklib +const my @ATTRIBUTES => qw( + name principal password code error skip_for_system_cracklib ); # A hash of attributes that should be put in the C struct as they literally # appear in the JSON, rather than as strings. (In other words, attributes # that are numbers, booleans, or C constants.) Only the keys are of interest. -Readonly my %IS_LITERAL_ATTRIBUTE => ( - code => 1, - skip_for_system_cracklib => 1 +const my %IS_LITERAL_ATTRIBUTE => ( + code => 1, + skip_for_system_cracklib => 1, ); ############################################################################## @@ -206,7 +206,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2020 Russ Allbery +Copyright 2020, 2023 Russ Allbery Copyright 2013 The Board of Trustees of the Leland Stanford Junior University diff --git a/tests/data/perlcriticrc b/tests/data/perlcriticrc index 60210a9..4643683 100644 --- a/tests/data/perlcriticrc +++ b/tests/data/perlcriticrc @@ -10,7 +10,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2018-2019 Russ Allbery +# Copyright 2018-2022 Russ Allbery # Copyright 2011-2013 # The Board of Trustees of the Leland Stanford Junior University # @@ -42,6 +42,20 @@ verbose = %f:%l:%c: [%p] %m (%e, Severity: %s)\n # group coding style. [-CodeLayout::ProhibitParensWithBuiltins] +# This conflicts with Subroutines::ProhibitExplicitReturnUndef and +# Subroutines::RequireFinalReturn, and I prefer the brevity of the simple +# return statement. I don't think the empty list versus undef behavior is +# that confusing. +# +# This should be Community::EmptyReturn, which is the new name of the module, +# but currently ignores have to use the Freenode::EmptyReturn name instead. +[-Community::EmptyReturn] +[-Freenode::EmptyReturn] + +# This recommends using given/when, but Perl has marked those as experimental +# and cautions against using when. +[-ControlStructures::ProhibitCascadingIfElse] + # Stanford's coding style allows postfix unless for flow control. There # doesn't appear to be any way to allow it only for flow control (the logic # for "if" and "when" appears to be special-cased), so we have to allow unless @@ -60,9 +74,9 @@ allow = unless # of $@ even if destructors run at exit from the eval block. [-ErrorHandling::RequireCheckingReturnValueOfEval] -# The default of 9 is too small and forces weird code contortions. -[InputOutput::RequireBriefOpen] -lines = 25 +# The default of 9 is too small and forces weird code contortions. After some +# experimentation, I've never found this helpful in driving useful refactors. +[-InputOutput::RequireBriefOpen] # This is correct 80% of the time, but it isn't correct for a lot of scripts # inside packages, where maintaining $VERSION isn't worth the effort. @@ -79,6 +93,12 @@ lines = 25 # Perl 5.20). See https://github.com/Perl-Critic/Perl-Critic/issues/578. [-References::ProhibitDoubleSigils] +# Five arguments to a method has seemed reasonable at least once: a pair of +# input file data and path, a pair of output file descriptor and path, and +# a dict of additional arguments. +[Subroutines::ProhibitManyArgs] +skip_object = 1 + # I generally don't want to require Readonly as a prerequisite for all my Perl # modules. [-ValuesAndExpressions::ProhibitConstantPragma] @@ -88,15 +108,15 @@ lines = 25 # independent of the algorithm, but don't do so for mathematical formulae. [-ValuesAndExpressions::ProhibitMagicNumbers] -# Increase this to six digits so that I'm not told to add underscores to -# port numbers (which is just silly). -[ValuesAndExpressions::RequireNumberSeparators] -min_value = 100000 +# This has never triggered on anything useful and keeps telling me to add +# underscores to UNIX timestamps and port numbers, which is just silly. +[-ValuesAndExpressions::RequireNumberSeparators] # IO::Uncompress::Gunzip puts the error message in a package variable. # Text::Wrap has a broken interface that requires use of package variables. +# YAML::XS also cannot be configured without package variables. [Variables::ProhibitPackageVars] -add_packages = IO::Uncompress::Gunzip Text::Wrap +add_packages = IO::Uncompress::Gunzip Text::Wrap YAML::XS # use English was one of the worst ideas in the history of Perl. It makes the # code slightly more readable for amateurs at the cost of confusing diff --git a/tests/data/perltidyrc b/tests/data/perltidyrc index c2d0e40..d9967be 100644 --- a/tests/data/perltidyrc +++ b/tests/data/perltidyrc @@ -6,6 +6,7 @@ # which can be found at . # # Written by Russ Allbery +# Copyright 2021-2023 Russ Allbery # Copyright 2012-2013 # The Board of Trustees of the Leland Stanford Junior University # @@ -17,9 +18,15 @@ # SPDX-License-Identifier: FSFAP -bbao # put line breaks before any operator +-bfvt=2 # no newline before "or" after closing brace -nbbc # don't force blank lines before comments (bad for else blocks) +-boc # do not re-break lists, since perltidy is awful at this +-cpb # put opening brace on same line as closing paren -ce # cuddle braces around else -l=79 # usually use 78, but don't want 79-long lines reformatted +-nlop # disable vertical alignment of logical and ternary expressions -pt=2 # don't add extra whitespace around parentheses -sbt=2 # ...or square brackets --sfs # no space before semicolon in for (not that I use this form) +-nsfs # no space before semicolon in for (not that I use this form) +-nvc # disable vertical alignment of = and similar symbols +-xci # improve indentation of nested structures diff --git a/tests/data/valgrind.supp b/tests/data/valgrind.supp index 5c10054..6e98780 100644 --- a/tests/data/valgrind.supp +++ b/tests/data/valgrind.supp @@ -11,7 +11,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2017-2018 Russ Allbery +# Copyright 2017-2018, 2020 Russ Allbery # Copyright 2011-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -70,6 +70,14 @@ fun:*alloc fun:_krb5_config_get_entry } +{ + heimdal-gss-cred + Memcheck:Leak + fun:calloc + obj:*libgssapi.so.* + obj:*libgssapi.so.* + fun:gss_acquire_cred +} { heimdal-gss-krb5-init Memcheck:Leak diff --git a/tests/docs/pod-spelling-t b/tests/docs/pod-spelling-t index 04a89e5..2ea5bf3 100755 --- a/tests/docs/pod-spelling-t +++ b/tests/docs/pod-spelling-t @@ -6,7 +6,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2016, 2019 Russ Allbery +# Copyright 2016, 2019, 2021 Russ Allbery # Copyright 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; diff --git a/tests/docs/pod-t b/tests/docs/pod-t index 7b53dda..be21ddf 100755 --- a/tests/docs/pod-t +++ b/tests/docs/pod-t @@ -7,7 +7,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2016, 2019 Russ Allbery +# Copyright 2016, 2019, 2021 Russ Allbery # Copyright 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -31,7 +31,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; diff --git a/tests/docs/spdx-license-t b/tests/docs/spdx-license-t index 24e4db0..cf407ad 100755 --- a/tests/docs/spdx-license-t +++ b/tests/docs/spdx-license-t @@ -9,7 +9,7 @@ # The canonical version of this file is maintained in the rra-c-util package, # which can be found at . # -# Copyright 2018-2020 Russ Allbery +# Copyright 2018-2023 Russ Allbery # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -31,7 +31,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; @@ -52,6 +52,9 @@ my @IGNORE = ( qr{ \A README ( [.] .* )? \z }xms, # Package license should be fine qr{ \A (Makefile|libtool) \z }xms, # Generated file qr{ [.] json \z }xms, # Data files without comment support + qr{ ~ \z }xms, # Backup files + qr{ [.] l?a \z }xms, # Created by libtool + qr{ [.] o \z }xms, # Compiler objects qr{ [.] output \z }xms, # Test data ); my @IGNORE_PATHS = ( @@ -74,10 +77,11 @@ my @IGNORE_PATHS = ( qr{ \A php/configure [.] (ac|in) \z }xms, # Created by phpize qr{ \A php/ltmain [.] sh \z }xms, # Created by phpize qr{ \A php/run-tests [.] php \z }xms, # Created by phpize + qr{ \A php/ .* [.] dep \z }xms, # Created by phpize qr{ \A python/ .* [.] egg-info/ }xms, # Python build files qr{ \A tests/config/ (?!README) }xms, # Test configuration - qr{ [.] l?a \z }xms, # Created by libtool - qr{ [.] o \z }xms, # Compiler objects + qr{ \A tests/tmp/ }xms, # Temporary test files + qr{ [.] mypy_cache/ }xms, # mypy caches ); ## use critic diff --git a/tests/perl/critic-t b/tests/perl/critic-t index 6f6e680..fedc380 100755 --- a/tests/perl/critic-t +++ b/tests/perl/critic-t @@ -6,7 +6,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2016, 2019 Russ Allbery +# Copyright 2016, 2019, 2021-2022 Russ Allbery # Copyright 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; @@ -53,22 +53,12 @@ automake_setup(); # Load prerequisite modules. use_prereq('Test::Perl::Critic'); -# Due to an annoying bug in Perl::Tidy 20130922, we cannot run tests if the -# source directory is read-only. It unconditionally tries to create a log -# file in the current directory and fails to run any checks if it cannot. -if (!-w File::Spec->curdir()) { - plan skip_all => 'Perl::Tidy needs writable source directory'; -} - # Force the embedded Perl::Tidy check to use the correct configuration. local $ENV{PERLTIDY} = test_file_path('data/perltidyrc'); # Import the configuration file. -Test::Perl::Critic->import(-profile => test_file_path('data/perlcriticrc')); +my $config_path = test_file_path('data/perlcriticrc'); +Test::Perl::Critic->import(-profile => $config_path); # Finally, run the actual tests. all_critic_ok(perl_dirs({ skip => [@CRITIC_IGNORE] })); - -# On Debian with perltidy 20130922-1, a perltidy.LOG file gets left behind -# in the current directory. Remove it if it exists. -unlink('perltidy.LOG'); diff --git a/tests/perl/minimum-version-t b/tests/perl/minimum-version-t index 420ce36..8cc62c4 100755 --- a/tests/perl/minimum-version-t +++ b/tests/perl/minimum-version-t @@ -10,7 +10,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2016, 2019-2020 Russ Allbery +# Copyright 2016, 2019-2021 Russ Allbery # Copyright 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -34,7 +34,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; diff --git a/tests/perl/strict-t b/tests/perl/strict-t index 6eae216..1c722ab 100755 --- a/tests/perl/strict-t +++ b/tests/perl/strict-t @@ -10,7 +10,7 @@ # which can be found at . # # Written by Russ Allbery -# Copyright 2016, 2019 Russ Allbery +# Copyright 2016, 2019, 2021 Russ Allbery # Copyright 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -34,7 +34,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; diff --git a/tests/plugin/heimdal-t.c b/tests/plugin/heimdal-t.c index 0c0afa5..9d36c57 100644 --- a/tests/plugin/heimdal-t.c +++ b/tests/plugin/heimdal-t.c @@ -2,6 +2,7 @@ * Test for the Heimdal shared module API. * * Written by Russ Allbery + * Copyright 2023 Russ Allbery * Copyright 2009, 2013-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -292,7 +293,7 @@ main(void) # endif /* !HAVE_CDB */ -# ifdef HAVE_SQLITE +# ifdef HAVE_SQLITE3 /* * If built with SQLite, set up krb5.conf to use a SQLite dictionary @@ -314,13 +315,13 @@ main(void) for (i = 0; i < ARRAY_SIZE(principal_tests); i++) is_password_test(verifier, &principal_tests[i]); -# else /* !HAVE_SQLITE */ +# else /* !HAVE_SQLITE3 */ /* Otherwise, mark the SQLite tests as skipped. */ count = ARRAY_SIZE(sqlite_tests) + ARRAY_SIZE(principal_tests); skip_block(count * 2, "not built with SQLite support"); -# endif /* !HAVE_SQLITE */ +# endif /* !HAVE_SQLITE3 */ /* Manually clean up after the results of make-krb5-conf. */ basprintf(&path, "%s/krb5.conf", tmpdir); diff --git a/tests/plugin/mit-t.c b/tests/plugin/mit-t.c index 485ff75..427e937 100644 --- a/tests/plugin/mit-t.c +++ b/tests/plugin/mit-t.c @@ -2,7 +2,7 @@ * Test for the MIT Kerberos shared module API. * * Written by Russ Allbery - * Copyright 2017, 2020 Russ Allbery + * Copyright 2017, 2020, 2023 Russ Allbery * Copyright 2010, 2013-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -413,7 +413,7 @@ main(void) # endif /* !HAVE_CDB */ -# ifdef HAVE_SQLITE +# ifdef HAVE_SQLITE3 /* * If built with SQLite, set up krb5.conf to use a SQLite dictionary @@ -447,13 +447,13 @@ main(void) is_password_test(ctx, vtable, data, &principal_tests[i]); vtable->close(ctx, data); -# else /* !HAVE_SQLITE */ +# else /* !HAVE_SQLITE3 */ /* Otherwise, mark the SQLite tests as skipped. */ count = ARRAY_SIZE(sqlite_tests) + ARRAY_SIZE(principal_tests); skip_block(count * 2 + 1, "not built with SQLite support"); -# endif /* !HAVE_SQLITE */ +# endif /* !HAVE_SQLITE3 */ /* Manually clean up after the results of make-krb5-conf. */ basprintf(&path, "%s/krb5.conf", tmpdir); diff --git a/tests/portable/snprintf-t.c b/tests/portable/snprintf-t.c deleted file mode 100644 index d14712f..0000000 --- a/tests/portable/snprintf-t.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * snprintf test suite. - * - * The canonical version of this file is maintained in the rra-c-util package, - * which can be found at . - * - * Written by Russ Allbery - * Copyright 2000-2006, 2018-2020 Russ Allbery - * Copyright 2009-2010 - * The Board of Trustees of the Leland Stanford Junior University - * Copyright 1995 Patrick Powell - * Copyright 2001 Hrvoje Niksic - * - * This code is based on code written by Patrick Powell (papowell@astart.com) - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions - * - * There is no SPDX-License-Identifier registered for this license. - */ - -#include -#include - -#include - -/* - * Disable the requirement that format strings be literals. We need variable - * formats for easy testing. - */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) || defined(__clang__) -# pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif - -/* - * Intentionally don't add the printf attribute here since we pass a - * zero-length printf format during testing and don't want warnings. - */ -int test_snprintf(char *str, size_t count, const char *fmt, ...); -int test_vsnprintf(char *str, size_t count, const char *fmt, va_list args); - -static const char string[] = "abcdefghijklmnopqrstuvwxyz0123456789"; - -/* clang-format off */ - -static const char *const fp_formats[] = { - "%-1.5f", "%1.5f", "%31.6f", "%10.5f", "% 10.5f", "%+22.6f", - "%+4.6f", "%01.3f", "%3.1f", "%3.2f", "%.0f", "%.1f", - "%f", - NULL -}; -static const char *const int_formats[] = { - "%-1.5d", "%1.5d", "%31.9d", "%5.5d", "%10.5d", "% 10.5d", - "%+22.30d", "%01.3d", "%4d", "%d", "%ld", NULL -}; -static const char *const uint_formats[] = { - "%-1.5lu", "%1.5lu", "%31.9lu", "%5.5lu", "%10.5lu", "% 10.5lu", - "%+6.30lu", "%01.3lu", "%4lu", "%lu", "%4lx", "%4lX", - "%01.3lx", "%1lo", NULL -}; -static const char *const llong_formats[] = { - "%lld", "%-1.5lld", "%1.5lld", "%123.9lld", "%5.5lld", - "%10.5lld", "% 10.5lld", "%+22.33lld", "%01.3lld", "%4lld", - NULL -}; -static const char *const ullong_formats[] = { - "%llu", "%-1.5llu", "%1.5llu", "%123.9llu", "%5.5llu", - "%10.5llu", "% 10.5llu", "%+22.33llu", "%01.3llu", "%4llu", - "%llx", "%llo", NULL -}; - -static const double fp_nums[] = { - -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, - 4.136, 0.1, 0.01, 0.001, 10.1, 0 -}; -static long int_nums[] = { - -1, 134, 91340, 341, 0203, 0 -}; -static unsigned long uint_nums[] = { - (unsigned long) -1, 134, 91340, 341, 0203, 0 -}; -static long long llong_nums[] = { - ~(long long) 0, /* All-1 bit pattern. */ - (~(unsigned long long) 0) >> 1, /* Largest signed long long. */ - -150, 134, 91340, 341, - 0 -}; -static unsigned long long ullong_nums[] = { - ~(unsigned long long) 0, /* All-1 bit pattern. */ - (~(unsigned long long) 0) >> 1, /* Largest signed long long. */ - 134, 91340, 341, - 0 -}; - -/* clang-format on */ - - -static void -test_format(bool trunc, const char *expected, int count, const char *format, - ...) -{ - char buf[128]; - int result; - va_list args; - - va_start(args, format); - result = test_vsnprintf(buf, trunc ? 32 : sizeof(buf), format, args); - va_end(args); - is_string(expected, buf, "format %s, wanted %s", format, expected); - is_int(count, result, "...and output length correct"); -} - - -int -main(void) -{ - int i, count; - unsigned int j; - long lcount; - char lgbuf[128]; - - plan(8 - + (18 + (ARRAY_SIZE(fp_formats) - 1) * ARRAY_SIZE(fp_nums) - + (ARRAY_SIZE(int_formats) - 1) * ARRAY_SIZE(int_nums) - + (ARRAY_SIZE(uint_formats) - 1) * ARRAY_SIZE(uint_nums) - + (ARRAY_SIZE(llong_formats) - 1) * ARRAY_SIZE(llong_nums) - + (ARRAY_SIZE(ullong_formats) - 1) * ARRAY_SIZE(ullong_nums)) - * 2); - - is_int(4, test_snprintf(NULL, 0, "%s", "abcd"), "simple string length"); - is_int(2, test_snprintf(NULL, 0, "%d", 20), "number length"); - is_int(7, test_snprintf(NULL, 0, "Test %.2s", "abcd"), "limited string"); - is_int(1, test_snprintf(NULL, 0, "%c", 'a'), "character length"); - is_int(0, test_snprintf(NULL, 0, ""), "empty format length"); - - test_format(true, "abcd", 4, "%s", "abcd"); - test_format(true, "20", 2, "%d", 20); - test_format(true, "Test ab", 7, "Test %.2s", "abcd"); - test_format(true, "a", 1, "%c", 'a'); - test_format(true, "", 0, ""); - test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%s", string); - test_format(true, "abcdefghij", 10, "%.10s", string); - test_format(true, " abcdefghij", 12, "%12.10s", string); - test_format(true, " abcdefghijklmnopqrstuvwxyz0", 40, "%40s", string); - test_format(true, "abcdefghij ", 14, "%-14.10s", string); - test_format(true, " abcdefghijklmnopq", 50, "%50s", string); - test_format(true, "%abcd%", 6, "%%%0s%%", "abcd"); - test_format(true, "", 0, "%.0s", string); - test_format(true, "abcdefghijklmnopqrstuvwxyz 444", 32, "%.26s %d", - string, 4444); - test_format(true, "abcdefghijklmnopqrstuvwxyz -2.", 32, "%.26s %.1f", - string, -2.5); - test_format(true, "abcdefghij4444", 14, "%.10s%n%d", string, &count, 4444); - is_int(10, count, "correct output from %%n"); - test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%n%s%ln", &count, - string, &lcount); - is_int(0, count, "correct output from two %%n"); - is_int(31, lcount, "correct output from long %%ln"); - test_format(true, "(null)", 6, "%s", (char *) NULL); - - for (i = 0; fp_formats[i] != NULL; i++) - for (j = 0; j < ARRAY_SIZE(fp_nums); j++) { - count = sprintf(lgbuf, fp_formats[i], fp_nums[j]); - test_format(false, lgbuf, count, fp_formats[i], fp_nums[j]); - } - for (i = 0; int_formats[i] != NULL; i++) - for (j = 0; j < ARRAY_SIZE(int_nums); j++) { - count = sprintf(lgbuf, int_formats[i], int_nums[j]); - test_format(false, lgbuf, count, int_formats[i], int_nums[j]); - } - for (i = 0; uint_formats[i] != NULL; i++) - for (j = 0; j < ARRAY_SIZE(uint_nums); j++) { - count = sprintf(lgbuf, uint_formats[i], uint_nums[j]); - test_format(false, lgbuf, count, uint_formats[i], uint_nums[j]); - } - for (i = 0; llong_formats[i] != NULL; i++) - for (j = 0; j < ARRAY_SIZE(llong_nums); j++) { - count = sprintf(lgbuf, llong_formats[i], llong_nums[j]); - test_format(false, lgbuf, count, llong_formats[i], llong_nums[j]); - } - for (i = 0; ullong_formats[i] != NULL; i++) - for (j = 0; j < ARRAY_SIZE(ullong_nums); j++) { - count = sprintf(lgbuf, ullong_formats[i], ullong_nums[j]); - test_format(false, lgbuf, count, ullong_formats[i], - ullong_nums[j]); - } - - return 0; -} diff --git a/tests/portable/snprintf.c b/tests/portable/snprintf.c deleted file mode 100644 index cff95b3..0000000 --- a/tests/portable/snprintf.c +++ /dev/null @@ -1,2 +0,0 @@ -#define TESTING 1 -#include diff --git a/tests/runtests.c b/tests/runtests.c index 1050120..72f4a70 100644 --- a/tests/runtests.c +++ b/tests/runtests.c @@ -8,7 +8,7 @@ * should be sent to the e-mail address below. This program is part of C TAP * Harness . * - * Copyright 2000-2001, 2004, 2006-2019 Russ Allbery + * Copyright 2000-2001, 2004, 2006-2019, 2022 Russ Allbery * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -156,10 +156,18 @@ #endif /* Test status codes. */ -enum test_status { TEST_FAIL, TEST_PASS, TEST_SKIP, TEST_INVALID }; +enum test_status { + TEST_FAIL, + TEST_PASS, + TEST_SKIP, + TEST_INVALID +}; /* Really, just a boolean, but this is more self-documenting. */ -enum test_verbose { CONCISE = 0, VERBOSE = 1 }; +enum test_verbose { + CONCISE = 0, + VERBOSE = 1 +}; /* Indicates the state of our plan. */ enum plan_status { @@ -272,6 +280,16 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ # endif #endif +/* + * Suppress the argument to __malloc__ in Clang (not supported in at least + * version 13) and GCC versions prior to 11. + */ +#if !defined(__attribute__) && !defined(__malloc__) +# if defined(__clang__) || __GNUC__ < 11 +# define __malloc__(dalloc) __malloc__ +# endif +#endif + /* * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ * settings that GCC does. For them, suppress warnings about unknown @@ -288,15 +306,15 @@ static void die(const char *, ...) static void sysdie(const char *, ...) __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); static void *x_calloc(size_t, size_t, const char *, int) - __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__)); + __attribute__((__alloc_size__(1, 2), __malloc__(free), __nonnull__)); static void *x_malloc(size_t, const char *, int) - __attribute__((__alloc_size__(1), __malloc__, __nonnull__)); + __attribute__((__alloc_size__(1), __malloc__(free), __nonnull__)); static void *x_reallocarray(void *, size_t, size_t, const char *, int) - __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4))); + __attribute__((__alloc_size__(2, 3), __malloc__(free), __nonnull__(4))); static char *x_strdup(const char *, const char *, int) - __attribute__((__malloc__, __nonnull__)); + __attribute__((__malloc__(free), __nonnull__)); static char *x_strndup(const char *, size_t, const char *, int) - __attribute__((__malloc__, __nonnull__)); + __attribute__((__malloc__(free), __nonnull__)); /* @@ -435,9 +453,9 @@ x_strndup(const char *s, size_t size, const char *file, int line) char *copy; /* Don't assume that the source string is nul-terminated. */ - for (p = s; (size_t)(p - s) < size && *p != '\0'; p++) + for (p = s; (size_t) (p - s) < size && *p != '\0'; p++) ; - len = (size_t)(p - s); + len = (size_t) (p - s); copy = (char *) malloc(len + 1); if (copy == NULL) sysdie("failed to strndup %lu bytes at %s line %d", diff --git a/tests/style/obsolete-strings-t b/tests/style/obsolete-strings-t index 02fd30c..430f072 100755 --- a/tests/style/obsolete-strings-t +++ b/tests/style/obsolete-strings-t @@ -9,7 +9,7 @@ # The canonical version of this file is maintained in the rra-c-util package, # which can be found at . # -# Copyright 2016, 2018-2019 Russ Allbery +# Copyright 2016, 2018-2020 Russ Allbery # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -31,7 +31,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; @@ -48,7 +48,8 @@ my @BAD_REGEXES = (qr{ http:// \S+ [.]eyrie[.]org }xms); my @BAD_STRINGS = qw(rra@stanford.edu RRA_MAINTAINER_TESTS); # File names to exclude from this check. -my %EXCLUDE = map { $_ => 1 } qw(NEWS obsolete-strings.t obsolete-strings-t); +my %EXCLUDE + = map { $_ => 1 } qw(NEWS changelog obsolete-strings.t obsolete-strings-t); # Only run this test for the package author, since it doesn't indicate any # user-noticable flaw in the package itself. diff --git a/tests/tap/basic.c b/tests/tap/basic.c index b5f42d0..8f44f15 100644 --- a/tests/tap/basic.c +++ b/tests/tap/basic.c @@ -13,7 +13,7 @@ * documentation is at . * * Written by Russ Allbery - * Copyright 2009-2019 Russ Allbery + * Copyright 2009-2019, 2021 Russ Allbery * Copyright 2001-2002, 2004-2008, 2011-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -349,7 +349,7 @@ finish(void) /* Print out the lazy plan if needed. */ fflush(stderr); - if (_lazy && _planned > 0) + if (_lazy) printf("1..%lu\n", _planned); /* Print out a summary of the results. */ @@ -899,9 +899,9 @@ bstrndup(const char *s, size_t n) size_t length; /* Don't assume that the source string is nul-terminated. */ - for (p = s; (size_t)(p - s) < n && *p != '\0'; p++) + for (p = s; (size_t) (p - s) < n && *p != '\0'; p++) ; - length = (size_t)(p - s); + length = (size_t) (p - s); copy = (char *) malloc(length + 1); if (copy == NULL) sysbail("failed to strndup %lu bytes", (unsigned long) length); diff --git a/tests/tap/basic.h b/tests/tap/basic.h index 45f15f2..3ae1d14 100644 --- a/tests/tap/basic.h +++ b/tests/tap/basic.h @@ -5,7 +5,7 @@ * documentation is at . * * Written by Russ Allbery - * Copyright 2009-2019 Russ Allbery + * Copyright 2009-2019, 2022 Russ Allbery * Copyright 2001-2002, 2004-2008, 2011-2012, 2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -35,6 +35,7 @@ #include /* va_list */ #include /* size_t */ +#include /* free */ #include /* @@ -129,17 +130,20 @@ void diag_file_remove(const char *file) __attribute__((__nonnull__)); /* Allocate memory, reporting a fatal error with bail on failure. */ void *bcalloc(size_t, size_t) - __attribute__((__alloc_size__(1, 2), __malloc__, __warn_unused_result__)); -void *bmalloc(size_t) - __attribute__((__alloc_size__(1), __malloc__, __warn_unused_result__)); + __attribute__((__alloc_size__(1, 2), __malloc__(free), + __warn_unused_result__)); +void *bmalloc(size_t) __attribute__((__alloc_size__(1), __malloc__(free), + __warn_unused_result__)); void *breallocarray(void *, size_t, size_t) - __attribute__((__alloc_size__(2, 3), __malloc__, __warn_unused_result__)); + __attribute__((__alloc_size__(2, 3), __malloc__(free), + __warn_unused_result__)); void *brealloc(void *, size_t) - __attribute__((__alloc_size__(2), __malloc__, __warn_unused_result__)); + __attribute__((__alloc_size__(2), __malloc__(free), + __warn_unused_result__)); char *bstrdup(const char *) - __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); + __attribute__((__malloc__(free), __nonnull__, __warn_unused_result__)); char *bstrndup(const char *, size_t) - __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); + __attribute__((__malloc__(free), __nonnull__, __warn_unused_result__)); /* * Macros that cast the return value from b* memory functions, making them @@ -153,16 +157,18 @@ char *bstrndup(const char *, size_t) * Find a test file under C_TAP_BUILD or C_TAP_SOURCE, returning the full * path. The returned path should be freed with test_file_path_free(). */ -char *test_file_path(const char *file) - __attribute__((__malloc__, __nonnull__, __warn_unused_result__)); void test_file_path_free(char *path); +char *test_file_path(const char *file) + __attribute__((__malloc__(test_file_path_free), __nonnull__, + __warn_unused_result__)); /* * Create a temporary directory relative to C_TAP_BUILD and return the path. * The returned path should be freed with test_tmpdir_free(). */ -char *test_tmpdir(void) __attribute__((__malloc__, __warn_unused_result__)); void test_tmpdir_free(char *path); +char *test_tmpdir(void) + __attribute__((__malloc__(test_tmpdir_free), __warn_unused_result__)); /* * Register a cleanup function that is called when testing ends. All such diff --git a/tests/tap/kerberos.c b/tests/tap/kerberos.c index 765d802..ae571dc 100644 --- a/tests/tap/kerberos.c +++ b/tests/tap/kerberos.c @@ -15,7 +15,7 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2017 Russ Allbery + * Copyright 2017, 2022 Russ Allbery * Copyright 2006-2007, 2009-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -211,9 +211,11 @@ kerberos_kinit(void) * process so that test programs that fork don't remove the ticket cache still * used by the main program. */ -static void -kerberos_free(void) +void +kerberos_free(struct kerberos_config *config_arg) { + if (config_arg != config) + bail("invalid argument to kerberos_free"); test_tmpdir_free(tmpdir_ticket); tmpdir_ticket = NULL; if (config != NULL) { @@ -225,7 +227,14 @@ kerberos_free(void) free(config->password); free(config->pkinit_principal); free(config->pkinit_cert); - free(config); + + /* + * Free config_arg rather than config, since otherwise cppcheck thinks + * that config_arg could be const, which while technically true would + * look very weird since config_arg is invalidated by calling this + * function. + */ + free(config_arg); config = NULL; } if (krb5ccname != NULL) { @@ -257,7 +266,7 @@ kerberos_cleanup(void) unlink(path); free(path); } - kerberos_free(); + kerberos_free(config); } @@ -273,7 +282,7 @@ kerberos_cleanup_handler(int success UNUSED, int primary) if (primary) kerberos_cleanup(); else - kerberos_free(); + kerberos_free(config); } diff --git a/tests/tap/kerberos.h b/tests/tap/kerberos.h index 0664905..d396de8 100644 --- a/tests/tap/kerberos.h +++ b/tests/tap/kerberos.h @@ -5,7 +5,7 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2017, 2020 Russ Allbery + * Copyright 2017, 2020, 2022 Russ Allbery * Copyright 2006-2007, 2009, 2011-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -76,6 +76,8 @@ BEGIN_DECLS * them in a Kerberos ticket cache, sets KRB5_KTNAME and KRB5CCNAME. It also * loads the principal and password from config/password, if it exists, and * stores the principal, password, username, and realm in the returned struct. + * The returned struct is also saved statically to allow for easier cleanup + * and thus cleaner valgrind output in tests. * * If there is no config/keytab file, KRB5_KTNAME and KRB5CCNAME won't be set * and the keytab field will be NULL. If there is no config/password file, @@ -87,9 +89,14 @@ BEGIN_DECLS * however, be called directly if for some reason the caller needs to delete * the Kerberos environment again. However, normally the caller can just call * kerberos_setup again. + * + * kerberos_free is an alternate way of calling kerberos_cleanup that + * satisfies the __malloc__ annotation requirements. There is normally no + * need to call it. */ +void kerberos_free(struct kerberos_config *); struct kerberos_config *kerberos_setup(enum kerberos_needs) - __attribute__((__malloc__)); + __attribute__((__malloc__(kerberos_free))); void kerberos_cleanup(void); /* diff --git a/tests/tap/macros.h b/tests/tap/macros.h index c2c8b5c..3361534 100644 --- a/tests/tap/macros.h +++ b/tests/tap/macros.h @@ -8,7 +8,7 @@ * This file is part of C TAP Harness. The current version plus supporting * documentation is at . * - * Copyright 2008, 2012-2013, 2015 Russ Allbery + * Copyright 2008, 2012-2013, 2015, 2022 Russ Allbery * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -69,6 +69,16 @@ # endif #endif +/* + * Suppress the argument to __malloc__ in Clang (not supported in at least + * version 13) and GCC versions prior to 11. + */ +#if !defined(__attribute__) && !defined(__malloc__) +# if defined(__clang__) || __GNUC__ < 11 +# define __malloc__(dalloc) __malloc__ +# endif +#endif + /* * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ * settings that GCC does. For them, suppress warnings about unknown diff --git a/tests/tap/perl/Test/RRA.pm b/tests/tap/perl/Test/RRA.pm index cd106d0..763f1fc 100644 --- a/tests/tap/perl/Test/RRA.pm +++ b/tests/tap/perl/Test/RRA.pm @@ -10,7 +10,7 @@ package Test::RRA; -use 5.008; +use 5.010; use base qw(Exporter); use strict; use warnings; @@ -46,13 +46,13 @@ our (@EXPORT_OK, $VERSION); # consistency is good). BEGIN { @EXPORT_OK = qw( - is_file_contents skip_unless_author skip_unless_automated use_prereq + is_file_contents skip_unless_author skip_unless_automated use_prereq ); # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '8.02'; + $VERSION = '10.05'; } # Compare a string to the contents of a file, similar to the standard is() @@ -83,11 +83,11 @@ sub is_file_contents { eval { require IPC::System::Simple; - my $tmp = File::Temp->new(); + my $tmp = File::Temp->new(); my $tmpname = $tmp->filename; print {$tmp} $got or BAIL_OUT("Cannot write to $tmpname: $!\n"); my @command = ('diff', '-u', $expected, $tmpname); - my $diff = IPC::System::Simple::capturex([0 .. 1], @command); + my $diff = IPC::System::Simple::capturex([0 .. 1], @command); diag($diff); }; if ($@) { @@ -165,15 +165,15 @@ sub use_prereq { ## no critic (ValuesAndExpressions::ProhibitImplicitNewlines) my ($result, $error, $sigdie); { - local $@ = undef; - local $! = undef; + local $@ = undef; + local $! = undef; local $SIG{__DIE__} = undef; $result = eval qq{ package $package; use $module $version \@imports; 1; }; - $error = $@; + $error = $@; $sigdie = $SIG{__DIE__} || undef; } @@ -196,7 +196,7 @@ __END__ =for stopwords Allbery Allbery's DESC bareword sublicense MERCHANTABILITY NONINFRINGEMENT -rra-c-util CPAN +rra-c-util CPAN diff =head1 NAME @@ -238,6 +238,14 @@ should be explicitly imported. =over 4 +=item is_file_contents(GOT, EXPECTED, MESSAGE) + +Check a string against the contents of a file, showing the differences if any +using diff (if IPC::System::Simple and diff are available). GOT is the output +the test received. EXPECTED is the path to a file containing the expected +output (not the output itself). MESSAGE is a message to display alongside the +test results. + =item skip_unless_author(DESC) Checks whether AUTHOR_TESTING is set in the environment and skips the whole @@ -275,7 +283,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2016, 2018-2019 Russ Allbery +Copyright 2016, 2018-2019, 2021 Russ Allbery Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior University diff --git a/tests/tap/perl/Test/RRA/Automake.pm b/tests/tap/perl/Test/RRA/Automake.pm index 16c9b01..6eee451 100644 --- a/tests/tap/perl/Test/RRA/Automake.pm +++ b/tests/tap/perl/Test/RRA/Automake.pm @@ -15,7 +15,7 @@ package Test::RRA::Automake; -use 5.008; +use 5.010; use base qw(Exporter); use strict; use warnings; @@ -34,7 +34,7 @@ my ($PERL_BLIB_ARCH, $PERL_BLIB_LIB); # the results in a use lib command below. BEGIN { $PERL_BLIB_ARCH = File::Spec->catdir(qw(perl blib arch)); - $PERL_BLIB_LIB = File::Spec->catdir(qw(perl blib lib)); + $PERL_BLIB_LIB = File::Spec->catdir(qw(perl blib lib)); # If C_TAP_BUILD is set, we can come up with better values. if (defined($ENV{C_TAP_BUILD})) { @@ -42,7 +42,7 @@ BEGIN { my @dirs = File::Spec->splitdir($dirs); pop(@dirs); $PERL_BLIB_ARCH = File::Spec->catdir(@dirs, qw(perl blib arch)); - $PERL_BLIB_LIB = File::Spec->catdir(@dirs, qw(perl blib lib)); + $PERL_BLIB_LIB = File::Spec->catdir(@dirs, qw(perl blib lib)); } } @@ -59,27 +59,27 @@ our (@EXPORT_OK, $VERSION); # consistency is good). BEGIN { @EXPORT_OK = qw( - all_files automake_setup perl_dirs test_file_path test_tmpdir + all_files automake_setup perl_dirs test_file_path test_tmpdir ); # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '8.02'; + $VERSION = '10.05'; } # Directories to skip globally when looking for all files, or for directories # that could contain Perl files. my @GLOBAL_SKIP = qw( - .git .pc _build autom4te.cache build-aux perl/_build perl/blib + .git .pc _build autom4te.cache build-aux perl/_build perl/blib ); # Additional paths to skip when building a list of all files in the # distribution. This primarily skips build artifacts that aren't interesting # to any of the tests. These match any path component. my @FILES_SKIP = qw( - .deps .dirstamp .libs aclocal.m4 config.h config.h.in config.h.in~ config.log - config.status configure + .deps .dirstamp .libs aclocal.m4 config.h config.h.in config.h.in~ + config.log config.status configure configure~ ); # The temporary directory created by test_tmpdir, if any. If this is set, @@ -94,7 +94,7 @@ sub all_files { my @files; # Turn the skip lists into hashes for ease of querying. - my %skip = map { $_ => 1 } @GLOBAL_SKIP; + my %skip = map { $_ => 1 } @GLOBAL_SKIP; my %files_skip = map { $_ => 1 } @FILES_SKIP; # Wanted function for find. Prune anything matching either of the skip @@ -103,11 +103,11 @@ sub all_files { my $file = $_; my $path = $File::Find::name; $path =~ s{ \A [.]/ }{}xms; - if ($skip{$path} || $files_skip{$file} || $file =~ m{ [.] lo \z }xms) { + if ($skip{$path} || $files_skip{$file} || $file =~ m{ [.]lo\z }xms) { $File::Find::prune = 1; return; } - if (-f $file) { + if (!-d $file) { push(@files, $path); } }; @@ -153,7 +153,7 @@ sub automake_setup { # Simplify relative paths at the end of the directory. my $ups = 0; - my $i = $#dirs; + my $i = $#dirs; while ($i > 2 && $dirs[$i] eq File::Spec->updir) { $ups++; $i--; @@ -186,7 +186,7 @@ sub automake_setup { @builddirs = File::Spec->splitdir($builddirs); pop(@builddirs); my $libdir = File::Spec->catdir(@builddirs, $LIBRARY_PATH); - my $path = File::Spec->catpath($buildvol, $libdir, q{}); + my $path = File::Spec->catpath($buildvol, $libdir, q{}); if (-d "$path/.libs") { $path .= '/.libs'; } @@ -226,7 +226,7 @@ sub perl_dirs { } # Convert the skip lists into hashes for convenience. - my %skip = map { $_ => 1 } @skip, 'tests'; + my %skip = map { $_ => 1 } @skip, 'tests'; my %skip_tests = map { $_ => 1 } @skip_tests; # Build the list of top-level directories to test. @@ -270,7 +270,7 @@ sub test_file_path { BASE: for my $base ($ENV{C_TAP_BUILD}, $ENV{C_TAP_SOURCE}) { next if !defined($base); - if (-f "$base/$file") { + if (-e "$base/$file") { return "$base/$file"; } } @@ -448,7 +448,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2014-2015, 2018-2020 Russ Allbery +Copyright 2014-2015, 2018-2021 Russ Allbery Copyright 2013 The Board of Trustees of the Leland Stanford Junior University diff --git a/tests/tap/perl/Test/RRA/Config.pm b/tests/tap/perl/Test/RRA/Config.pm index 7064140..0c6973c 100644 --- a/tests/tap/perl/Test/RRA/Config.pm +++ b/tests/tap/perl/Test/RRA/Config.pm @@ -9,7 +9,7 @@ package Test::RRA::Config; -use 5.008; +use 5.010; use base qw(Exporter); use strict; use warnings; @@ -24,15 +24,15 @@ our (@EXPORT_OK, $VERSION); # consistency is good). BEGIN { @EXPORT_OK = qw( - $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH - $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE - @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ + $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH + $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE + @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ ); # This version should match the corresponding rra-c-util release, but with # two digits for the minor version, including a leading zero if necessary, # so that it will sort properly. - $VERSION = '8.02'; + $VERSION = '10.05'; } # If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for @@ -58,7 +58,7 @@ our $COVERAGE_LEVEL = 100; our @COVERAGE_SKIP_TESTS; our @CRITIC_IGNORE; our $LIBRARY_PATH; -our $MINIMUM_VERSION = '5.008'; +our $MINIMUM_VERSION = '5.010'; our %MINIMUM_VERSION; our @MODULE_VERSION_IGNORE; our @POD_COVERAGE_EXCLUDE; @@ -121,9 +121,9 @@ this setting. =item @CRITIC_IGNORE -Additional directories to ignore when doing recursive perlcritic testing. The -contents of this directory must be either top-level directory names or -directory names starting with F. +Additional files or directories to ignore when doing recursive perlcritic +testing. To ignore files that will be installed, the path should start with +F. =item $LIBRARY_PATH @@ -135,7 +135,7 @@ that Perl scripts can pass a syntax check. =item $MINIMUM_VERSION Default minimum version requirement for included Perl scripts. If not given, -defaults to 5.008. +defaults to 5.010. =item %MINIMUM_VERSION @@ -183,7 +183,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2015-2016, 2019 Russ Allbery +Copyright 2015-2016, 2019, 2021 Russ Allbery Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior University diff --git a/tests/tap/process.c b/tests/tap/process.c index 2f797f8..28bdbe2 100644 --- a/tests/tap/process.c +++ b/tests/tap/process.c @@ -14,7 +14,8 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2002, 2004-2005, 2013, 2016-2017 Russ Allbery + * Copyright 2002, 2004-2005, 2013, 2016-2017, 2022 + * Russ Allbery * Copyright 2009-2011, 2013-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -412,6 +413,8 @@ process_start_internal(const char *const argv[], const char *pidfile, const char *path_fakeroot = PATH_FAKEROOT; /* Check prerequisites. */ + if (argv == NULL) + bail("argv for process_start is NULL"); if (fakeroot && path_fakeroot[0] == '\0') skip_all("fakeroot not found"); diff --git a/tests/tools/heimdal-history-t b/tests/tools/heimdal-history-t index f52467c..94d8e5a 100755 --- a/tests/tools/heimdal-history-t +++ b/tests/tools/heimdal-history-t @@ -3,7 +3,7 @@ # Test suite for Heimdal per-principal history. # # Written by Russ Allbery -# Copyright 2020 Russ Allbery +# Copyright 2020, 2023 Russ Allbery # Copyright 2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -52,7 +52,7 @@ sub run_heimdal_history { $in .= "end\n"; # Find the newly-built history and strengty programs. - my $history = test_file_path('../tools/heimdal-history'); + my $history = test_file_path('../tools/heimdal-history'); my $strength = test_file_path('../tools/heimdal-strength'); # Get a temporary directory for statistics and history databases. @@ -91,8 +91,8 @@ sub run_heimdal_history { # Throws: Text exception on failure to run the test program sub check_password { my ($test_ref) = @_; - my $principal = $test_ref->{principal}; - my $password = $test_ref->{password}; + my $principal = $test_ref->{principal}; + my $password = $test_ref->{password}; # Run the heimdal-strength command. my ($status, $out, $err) = run_heimdal_history($principal, $password); @@ -105,9 +105,9 @@ sub check_password { is($status, $test_ref->{status} || 0, "$test_ref->{name} (status)"); if (defined($test_ref->{error})) { is($err, $test_ref->{error}, '...error message'); - is($out, q{}, '...no output'); + is($out, q{}, '...no output'); } else { - is($err, q{}, '...no errors'); + is($err, q{}, '...no errors'); is($out, 'APPROVED', '...approved'); } return; @@ -156,22 +156,24 @@ for my $test_ref (@{$tests}) { my %lengthdb; my $mode = O_CREAT | O_RDWR; my $path = test_tmpdir() . '/lengths.db'; -ok(tie(%lengthdb, 'DB_File::Lock', [$path, $mode, oct(600)], 'write'), - 'Length database exists'); +ok( + tie(%lengthdb, 'DB_File::Lock', [$path, $mode, oct(600)], 'write'), + 'Length database exists', +); is_deeply(\%lengthdb, \%lengths, '...and contents are correct'); # Check the same password twice in a row with the -c option. It should be # accepted both times, instead of rejected the second time as a duplicate. my ($status, $out, $err) = run_heimdal_history('test@EXAMPLE.ORG', 'somepass', '-c'); -is($status, 0, 'First password check succeeds'); -is($out, "APPROVED\n", '...with correct output'); -is($err, q{}, '...and no error'); +is($status, 0, 'First password check succeeds'); +is($out, "APPROVED\n", '...with correct output'); +is($err, q{}, '...and no error'); ($status, $out, $err) = run_heimdal_history('test@EXAMPLE.ORG', 'somepass', '-c'); -is($status, 0, 'Second password check still succeeds'); -is($out, "APPROVED\n", '...with correct output'); -is($err, q{}, '...and no error'); +is($status, 0, 'Second password check still succeeds'); +is($out, "APPROVED\n", '...with correct output'); +is($err, q{}, '...and no error'); # Clean up the databases and lock files on any exit. END { diff --git a/tests/tools/heimdal-strength-t b/tests/tools/heimdal-strength-t index 5e7b1cb..15cded0 100755 --- a/tests/tools/heimdal-strength-t +++ b/tests/tools/heimdal-strength-t @@ -3,13 +3,13 @@ # Test suite for basic Heimdal external strength checking functionality. # # Written by Russ Allbery -# Copyright 2016-2017, 2020 Russ Allbery +# Copyright 2016-2017, 2020, 2023 Russ Allbery # Copyright 2009, 2012-2014 # The Board of Trustees of the Leland Stanford Junior University # # SPDX-License-Identifier: MIT -use 5.006; +use 5.010; use strict; use warnings; @@ -22,7 +22,7 @@ use Test::RRA::Automake qw(test_file_path); use_prereq('IPC::Run', 'run'); use_prereq('JSON'); use_prereq('Perl6::Slurp', 'slurp'); -use_prereq('Test::More', '0.87_01'); +use_prereq('Test::More', '0.87_01'); # Data directory to use for dictionaries. my $DATADIR = $ENV{BUILD} ? "$ENV{BUILD}/data" : 'tests/data'; @@ -35,6 +35,7 @@ my $DATADIR = $ENV{BUILD} ? "$ENV{BUILD}/data" : 'tests/data'; # config - Hash of Kerberos configuration to use # needs - Dictionary type name we have to have to run this test # tests - List of classes of tests to run (JSON files in tests/data/passwords) +#<<< my @TESTS = ( { title => 'Generic tests', @@ -83,6 +84,7 @@ my @TESTS = ( title => 'CDB tests', config => { password_dictionary_cdb => test_file_path('data/wordlist.cdb') }, + needs => 'CDB', tests => [qw(cdb principal)], }, { @@ -91,9 +93,11 @@ my @TESTS = ( password_dictionary_sqlite => test_file_path('data/wordlist.sqlite'), }, + needs => 'SQLite', tests => [qw(sqlite principal)], }, ); +#>>> # Run the newly-built heimdal-strength command and return the status, output, # and error output as a list. If told to expect an immediate error, does not @@ -122,7 +126,7 @@ sub run_heimdal_strength { # Run the password strength checker. my ($out, $err); my $harness = run([$program, $principal], \$in, \$out, \$err); - my $status = $? >> 8; + my $status = $? >> 8; # Return the results. return ($status, $out, $err); @@ -143,8 +147,8 @@ sub run_heimdal_strength { # Throws: Text exception on failure to run the test program sub check_password { my ($test_ref) = @_; - my $principal = $test_ref->{principal}; - my $password = $test_ref->{password}; + my $principal = $test_ref->{principal}; + my $password = $test_ref->{password}; # Run the heimdal-strength command. my ($status, $out, $err) = run_heimdal_strength($principal, $password); @@ -157,9 +161,9 @@ sub check_password { is($status, $test_ref->{status} || 0, "$test_ref->{name} (status)"); if (defined($test_ref->{error})) { is($err, $test_ref->{error}, '...error message'); - is($out, q{}, '...no output'); + is($out, q{}, '...no output'); } else { - is($err, q{}, '...no errors'); + is($err, q{}, '...no errors'); is($out, 'APPROVED', '...approved'); } return; @@ -176,9 +180,9 @@ sub create_krb5_conf { my ($settings_ref) = @_; # Paths for krb5.conf creation. - my $old = test_file_path('data/krb5.conf'); + my $old = test_file_path('data/krb5.conf'); my $tmpdir = $ENV{BUILD} ? "$ENV{BUILD}/tmp" : 'tests/tmp'; - my $new = "$tmpdir/krb5.conf"; + my $new = "$tmpdir/krb5.conf"; # Create a temporary directory for the new file. if (!-d $tmpdir) { @@ -272,10 +276,10 @@ sub run_password_tests { # # Returns: undef sub test_require_classes_syntax { - my ($bad_class) = @_; + my ($bad_class) = @_; my $error_prefix = 'Cannot initialize strength checking'; - my $bad_message = 'bad character class requirement in configuration'; - my $bad_minimum = 'bad character class minimum in configuration'; + my $bad_message = 'bad character class requirement in configuration'; + my $bad_minimum = 'bad character class minimum in configuration'; # Run heimdal-strength. my $krb5_conf = create_krb5_conf({ require_classes => $bad_class }); @@ -283,7 +287,7 @@ sub test_require_classes_syntax { my ($status, $output, $err) = run_heimdal_strength('test', 'password', 1); # Check the results. - is($status, 1, "Bad class specification '$bad_class' (status)"); + is($status, 1, "Bad class specification '$bad_class' (status)"); is($output, q{}, '...no output'); my $expected; if ($bad_class =~ m{ \A (\d+ [^-]*) \z | : (\d+) \z }xms) { @@ -332,13 +336,13 @@ my $krb5_conf = create_krb5_conf({ require_classes => 'bogus' }); local $ENV{KRB5_CONFIG} = $krb5_conf; my $error_prefix = 'Cannot initialize strength checking'; my ($status, $output, $err) = run_heimdal_strength('test', 'password', 1); -is($status, 1, 'Bad character class (status)'); +is($status, 1, 'Bad character class (status)'); is($output, q{}, '...no output'); is($err, "$error_prefix: unknown character class bogus\n", '...correct error'); # Test a variety of configuration syntax errors in require_classes. my @bad_classes = qw( - 8 8bogus 8:bogus 4-:bogus 4-bogus 4-8bogus 10:3 10-11:5 + 8 8bogus 8:bogus 4-:bogus 4-bogus 4-8bogus 10:3 10-11:5 ); for my $bad_class (@bad_classes) { test_require_classes_syntax($bad_class); @@ -348,7 +352,7 @@ for my $bad_class (@bad_classes) { END { my $tmpdir = $ENV{BUILD} ? "$ENV{BUILD}/tmp" : 'tests/tmp'; my $config = "$tmpdir/krb5.conf"; - if (-f $config) { + if (-e $config) { unlink($config) or warn "Cannot remove $config\n"; rmdir($tmpdir); } diff --git a/tests/tools/wordlist-sqlite-t b/tests/tools/wordlist-sqlite-t index e21c867..8f7c40e 100755 --- a/tests/tools/wordlist-sqlite-t +++ b/tests/tools/wordlist-sqlite-t @@ -3,7 +3,7 @@ # Test suite for krb5-strength-wordlist SQLite database generation # # Written by Russ Allbery -# Copyright 2020 Russ Allbery +# Copyright 2020, 2023 Russ Allbery # Copyright 2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -23,7 +23,7 @@ use Test::More; # Load prerequisite modules. use_prereq('DBI'); use_prereq('DBD::SQLite'); -use_prereq('IPC::Run', 'run'); +use_prereq('IPC::Run', 'run'); use_prereq('Perl6::Slurp', 'slurp'); # Set up for testing of an Automake project. @@ -46,7 +46,7 @@ sub run_wordlist { my $wordlist = test_file_path('../tools/krb5-strength-wordlist'); # Ensure the output file does not exist. - if (-f $output) { + if (-e $output) { unlink($output) or BAIL_OUT("cannot delete $output: $!"); } @@ -56,9 +56,9 @@ sub run_wordlist { my $status = ($? >> 8); # Check the results. - is($status, 0, 'krb5-strength-wordlist -s'); - is($out, q{}, '...with no output'); - is($err, q{}, '...and no errors'); + is($status, 0, 'krb5-strength-wordlist -s'); + is($out, q{}, '...with no output'); + is($err, q{}, '...and no errors'); # Return the newly-created database. return $output; @@ -67,7 +67,7 @@ sub run_wordlist { # Read the word list that we'll use for testing so that we can validate the # contents of the generated SQLite database. my $wordlist = test_file_path('data/wordlist'); -my @words = slurp($wordlist); +my @words = slurp($wordlist); chomp(@words); # Declare the plan now that we know how many tests there will be. There is @@ -86,7 +86,7 @@ ok(defined($dbh), 'Opening SQLite database succeeded'); # Walk through every row in the passwords table and ensure that the drowssap # column is the reverse of the password column. Accumulate the passwords so # that we can check against the contents of the word list. -my $sql = 'SELECT PASSWORD, DROWSSAP FROM PASSWORDS'; +my $sql = 'SELECT PASSWORD, DROWSSAP FROM PASSWORDS'; my $data_ref = $dbh->selectall_arrayref($sql); my @got; for my $row (@{$data_ref}) { diff --git a/tests/tools/wordlist-t b/tests/tools/wordlist-t index 07a2fc8..6cd4fe4 100755 --- a/tests/tools/wordlist-t +++ b/tests/tools/wordlist-t @@ -3,7 +3,7 @@ # Test suite for krb5-strength-wordlist filtering functions. # # Written by Russ Allbery -# Copyright 2016, 2020 Russ Allbery +# Copyright 2016, 2020, 2023 Russ Allbery # Copyright 2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -22,7 +22,7 @@ use Encode qw(encode); use Test::More; # Load prerequisite modules. -use_prereq('IPC::Run', 'run'); +use_prereq('IPC::Run', 'run'); use_prereq('Perl6::Slurp', 'slurp'); # Set up for testing of an Automake project. @@ -50,9 +50,9 @@ sub run_wordlist { my $status = ($? >> 8); # Check the results. - is($status, 0, "krb5-strength-wordlist @args"); - is($out, q{}, '...with no output'); - is($err, q{}, '...and no errors'); + is($status, 0, "krb5-strength-wordlist @args"); + is($out, q{}, '...with no output'); + is($err, q{}, '...and no errors'); return; } @@ -65,7 +65,9 @@ my @wordlist = slurp(test_file_path('data/wordlist')); my @filtered = grep { !m{d}xms && length >= 8 } @wordlist; # Add a non-ASCII word to test non-ASCII filtering. -push(@wordlist, encode('UTF-8', "\N{U+0639}\N{U+0631}\N{U+0628}\N{U+649}")); +## no critic (ValuesAndExpressions::ProhibitEscapedCharacters) +push(@wordlist, encode('UTF-8', "\x{0639}\x{0631}\x{0628}\x{0649}")); +## use critic # Write the new wordlist, including the non-ASCII word, to a new file. my $tmpdir = test_tmpdir(); diff --git a/tests/valgrind/logs-t b/tests/valgrind/logs-t index 1f65902..5444d00 100755 --- a/tests/valgrind/logs-t +++ b/tests/valgrind/logs-t @@ -5,7 +5,7 @@ # The canonical version of this file is maintained in the rra-c-util package, # which can be found at . # -# Copyright 2018-2019 Russ Allbery +# Copyright 2018-2019, 2021 Russ Allbery # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -27,7 +27,7 @@ # # SPDX-License-Identifier: MIT -use 5.008; +use 5.010; use strict; use warnings; diff --git a/tools/heimdal-history b/tools/heimdal-history index 525e6df..63cc345 100755 --- a/tools/heimdal-history +++ b/tools/heimdal-history @@ -17,14 +17,14 @@ use strict; use warnings; use DB_File::Lock; +use Const::Fast qw(const); use Crypt::PBKDF2; use Fcntl qw(O_CREAT O_RDWR); use File::Basename qw(basename); use Getopt::Long::Descriptive qw(describe_options); use IPC::Run qw(run); -use JSON qw(encode_json decode_json); +use JSON::MaybeXS qw(encode_json decode_json); use POSIX qw(setgid setuid); -use Readonly; use Sys::Syslog qw(openlog syslog LOG_AUTH LOG_INFO LOG_WARNING); # The most convenient interface to Berkeley DB files is ties. @@ -33,40 +33,40 @@ use Sys::Syslog qw(openlog syslog LOG_AUTH LOG_INFO LOG_WARNING); # The number of PBKDF2 iterations to use when hashing passwords. This number # should be chosen so as to force the hash operation to take approximately 0.1 # seconds on current hardware. -Readonly my $HASH_ITERATIONS => 40128; +const my $HASH_ITERATIONS => 40128; # Path to the history database. Currently, this must be a Berkeley DB file in # the old DB_HASH format. Keys will be principal names, and values will be a # JSON array of hashes. Each hash will have two keys: timestamp, which holds # the seconds since UNIX epoch at which the history entry was stored, and # hash, which holds the Crypt::PBKDF2 LDAP-style password hash. -Readonly my $HISTORY_PATH => '/var/lib/heimdal-history/history.db'; +const my $HISTORY_PATH => '/var/lib/heimdal-history/history.db'; # User and group used to do all password history lookups and writes, assuming # that this program is invoked as root and can therefore change UID and GID. -Readonly my $HISTORY_USER => '_history'; -Readonly my $HISTORY_GROUP => '_history'; +const my $HISTORY_USER => '_history'; +const my $HISTORY_GROUP => '_history'; # Path to the Berkeley DB file (DB_HASH format) that stores statistics on # password length of accepted passwords. Each successful password validation # will increase the counter for that length. This is read and written with # $HISTORY_USER and $HISTORY_GROUP. -Readonly my $LENGTH_STATS_PATH => '/var/lib/heimdal-history/lengths.db'; +const my $LENGTH_STATS_PATH => '/var/lib/heimdal-history/lengths.db'; # The message to return to the user if we reject the password because it was # found in the user's history. -Readonly my $REJECT_MESSAGE => 'Password was previously used'; +const my $REJECT_MESSAGE => 'Password was previously used'; # The path to the external strength checking program to run. This is done # first before checking history, and if it fails, that failure is returned as # the failure for this program. -Readonly my $STRENGTH_PROGRAM => '/usr/bin/heimdal-strength'; +const my $STRENGTH_PROGRAM => '/usr/bin/heimdal-strength'; # User and group used to do password strength checking. Generally, this # doesn't require any privileges since the strength dictionary is # world-readable. -Readonly my $STRENGTH_USER => 'nobody'; -Readonly my $STRENGTH_GROUP => 'nogroup'; +const my $STRENGTH_USER => 'nobody'; +const my $STRENGTH_GROUP => 'nogroup'; # Global boolean variable saying whether to log with syslog. This is set # based on the presence of the -q (--quiet) command-line option. @@ -165,9 +165,9 @@ sub log_error { return; } my $message = encode_log_message( - action => 'check', + action => 'check', principal => $principal, - error => $error, + error => $error, ); syslog(LOG_WARNING, '%s', $message); return; @@ -199,9 +199,9 @@ sub log_result { # Create the message. my %message = ( - action => 'check', + action => 'check', principal => $principal, - result => $result, + result => $result, ); if ($result eq 'rejected' && defined($reason)) { $message{reason} = $reason; @@ -299,7 +299,7 @@ sub is_in_history { sub find_iteration_count { my ($target, $delta) = @_; my $high = 0; - my $low = 0; + my $low = 0; # A static password to use for benchmarking. my $password = 'this is a benchmark'; @@ -313,7 +313,7 @@ sub find_iteration_count { require Benchmark; my $iterations = $HASH_ITERATIONS; while (1) { - my $hash = sub { password_hash($password, $iterations) }; + my $hash = sub { password_hash($password, $iterations) }; my $times = Benchmark::timethis(20, $hash, q{}, 'none'); # Extract the CPU time from the formatted time string. This will be @@ -377,9 +377,10 @@ sub check_history { { my %history; my $mode = O_CREAT | O_RDWR; - tie(%history, 'DB_File::Lock', $path, $mode, oct(600), $DB_HASH, - 'write') - or die "$0: cannot open $path: $!\n"; + tie( + %history, 'DB_File::Lock', $path, $mode, oct(600), $DB_HASH, + 'write', + ) or die "$0: cannot open $path: $!\n"; $history_json = $history{$principal}; } @@ -487,18 +488,18 @@ sub update_length_counts { # $principal - Principal attempting to change their password # $password - The new password # -# Returns: Scalar context: true if the password was accepted, false otherwise -# List context: whether the password is okay, the exit status of the -# quality checking program, and the error message if the first -# element is false -# Throws: Text exception on failure to execute the program, or read or write -# from it or to it, or if it fails without an error +# Returns: A list of three elements: +# - whether the password is okay +# - the exit status of the quality checking program +# - the error message if the first element is false +# Throws: Text exception on failure to execute the program, or read or +# write from it or to it, or if it fails without an error sub strength_check { my ($path, $principal, $password) = @_; # Run the external quality checking program. If we're root, we'll run it # as the strength checking user and group. - my $in = "principal: $principal\nnew-password: $password\nend\n"; + my $in = "principal: $principal\nnew-password: $password\nend\n"; my $init = sub { drop_privileges($STRENGTH_USER, $STRENGTH_GROUP) }; my ($out, $err); run([$path, $principal], \$in, \$out, \$err, init => $init); @@ -517,7 +518,7 @@ sub strength_check { } # Return the results. - return wantarray ? ($okay, $err, $status) : $okay; + return ($okay, $err, $status); } # Read a Heimdal external password quality checking request from the provided @@ -536,8 +537,7 @@ sub strength_check { # # $fh - File handle from which to read # -# Returns: Scalar context: the password -# List context: a list of the password and the principal +# Returns: List of the password and the principal # Throws: Text exception on any protocol violations or IO errors sub read_change_data { my ($fh) = @_; @@ -569,9 +569,7 @@ sub read_change_data { } # Return the results. - my $password = $data{'new-password'}; - my $principal = $data{principal}; - return wantarray ? ($password, $principal) : $password; + return ($data{'new-password'}, $data{principal}); } ############################################################################## @@ -586,6 +584,7 @@ my $fullpath = $0; local $0 = basename($0); # Parse the argument list. +#<<< my ($opt, $usage) = describe_options( '%c %o', ['benchmark|b=f', 'Benchmark hash iterations for this target time'], @@ -597,6 +596,7 @@ my ($opt, $usage) = describe_options( ['stats|S=s', 'Path to database of length statistics'], ['strength|s=s', 'Path to strength checking program to run'], ); +#>>> if ($opt->help) { print {*STDOUT} $usage->text or die "$0: cannot write to standard output: $!\n"; @@ -607,7 +607,7 @@ if ($opt->help) { exec('perldoc', '-t', $fullpath); } my $database = $opt->database || $HISTORY_PATH; -my $stats_db = $opt->stats || $LENGTH_STATS_PATH; +my $stats_db = $opt->stats || $LENGTH_STATS_PATH; my $strength = $opt->strength || $STRENGTH_PROGRAM; # If asked to do benchmarking, ignore other arguments and just do that. @@ -905,7 +905,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017, 2020 Russ Allbery +Copyright 2016-2017, 2020, 2023 Russ Allbery Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior University diff --git a/tools/krb5-strength-wordlist b/tools/krb5-strength-wordlist index 81bb4da..e9886e4 100755 --- a/tools/krb5-strength-wordlist +++ b/tools/krb5-strength-wordlist @@ -73,13 +73,13 @@ sub write_cdb { my ($in_fh, $output, $filter) = @_; # Check that the output CDB file doesn't exist. - if (-f $output) { + if (-e $output) { die "$0: output file $output already exists\n"; } # Create a temporary file to write the CDB input into. my $tmp = $output . '.data'; - if (-f $tmp) { + if (-e $tmp) { die "$0: temporary output file $tmp already exists\n"; } open(my $tmp_fh, '>', $tmp); @@ -122,7 +122,7 @@ sub write_sqlite { my ($in_fh, $output, $filter) = @_; # Check that the output SQLite file doesn't exist. - if (-f $output) { + if (-e $output) { die "$0: output file $output already exists\n"; } @@ -205,8 +205,8 @@ sub build_filter { # Build a filter from our command-line parameters. This is an anonymous # sub that returns true to keep a word and false otherwise. my $filter = sub { - my ($word) = @_; - my $length = length($word); + my ($word) = @_; + my $length = length($word); my $min_length = $config_ref->{'min-length'}; my $max_length = $config_ref->{'max-length'}; @@ -247,8 +247,8 @@ local $0 = basename($0); # Parse the argument list. my %config; my @options = ( - 'ascii|a', 'cdb|c=s', 'max-length|L=i', 'min-length|l=i', - 'manual|man|m', 'output|o=s', 'sqlite|s=s', 'exclude|x=s@', + 'ascii|a', 'cdb|c=s', 'max-length|L=i', 'min-length|l=i', + 'manual|man|m', 'output|o=s', 'sqlite|s=s', 'exclude|x=s@', ); Getopt::Long::config('bundling', 'no_ignore_case'); GetOptions(\%config, @options); @@ -426,7 +426,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2016, 2020 Russ Allbery +Copyright 2016, 2020, 2023 Russ Allbery Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior University diff --git a/util/macros.h b/util/macros.h index 612a88c..932674b 100644 --- a/util/macros.h +++ b/util/macros.h @@ -32,10 +32,10 @@ #define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)]) /* Used to name the elements of the array passed to pipe. */ -#define PIPE_READ 0 -#define PIPE_WRITE 1 +#define PIPE_READ 0 +#define PIPE_WRITE 1 /* Used for unused parameters to silence gcc warnings. */ -#define UNUSED __attribute__((__unused__)) +#define UNUSED __attribute__((__unused__)) #endif /* UTIL_MACROS_H */ diff --git a/util/xmalloc.c b/util/xmalloc.c index e8a9a82..43f26a1 100644 --- a/util/xmalloc.c +++ b/util/xmalloc.c @@ -63,7 +63,7 @@ * which can be found at . * * Written by Russ Allbery - * Copyright 2015 Russ Allbery + * Copyright 2015, 2023 Russ Allbery * Copyright 2012-2014 * The Board of Trustees of the Leland Stanford Junior University * Copyright 2004-2006 Internet Systems Consortium, Inc. ("ISC") @@ -137,7 +137,7 @@ x_calloc(size_t n, size_t size, const char *file, int line) size = (size > 0) ? size : 1; p = calloc(n, size); while (p == NULL) { - (*xmalloc_error_handler)("calloc", n * size, file, line); + (*xmalloc_error_handler)("calloc", n *size, file, line); p = calloc(n, size); } return p; @@ -150,11 +150,23 @@ x_realloc(void *p, size_t size, const char *file, int line) void *newp; newp = realloc(p, size); - while (newp == NULL && size > 0) { + if (size == 0) + return newp; + + /* + * GCC 13.2.0 (and some earlier versions) misdiagnose this error + * handling as a use-after-free of p, but the C standard guarantees + * that if realloc fails (which is true in every case when it returns + * NULL when size > 0), p is unchanged and still valid. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuse-after-free" + while (newp == NULL) { (*xmalloc_error_handler)("realloc", size, file, line); newp = realloc(p, size); } return newp; +#pragma GCC diagnostic pop } @@ -164,10 +176,23 @@ x_reallocarray(void *p, size_t n, size_t size, const char *file, int line) void *newp; newp = reallocarray(p, n, size); - while (newp == NULL && size > 0 && n > 0) { - (*xmalloc_error_handler)("reallocarray", n * size, file, line); + if (size == 0 || n == 0) + return newp; + + /* + * GCC 13.2.0 (and some earlier versions) misdiagnose this error + * handling as a use-after-free of p, but the documentation of + * reallocarray guarantees that if reallocarray fails (which is true in + * every case when it returns NULL when size > 0 and n > 0), p is + * unchanged and still valid. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuse-after-free" + while (newp == NULL) { + (*xmalloc_error_handler)("reallocarray", n *size, file, line); newp = reallocarray(p, n, size); } +#pragma GCC diagnostic pop return newp; } @@ -202,7 +227,7 @@ x_strndup(const char *s, size_t size, const char *file, int line) char *copy; /* Don't assume that the source string is nul-terminated. */ - for (p = s; (size_t)(p - s) < size && *p != '\0'; p++) + for (p = s; (size_t) (p - s) < size && *p != '\0'; p++) ; length = p - s; copy = malloc(length + 1); diff --git a/util/xmalloc.h b/util/xmalloc.h index 02c5431..543e024 100644 --- a/util/xmalloc.h +++ b/util/xmalloc.h @@ -5,6 +5,7 @@ * which can be found at . * * Written by Russ Allbery + * Copyright 2022 Russ Allbery * Copyright 2010, 2012-2014 * The Board of Trustees of the Leland Stanford Junior University * Copyright 2004-2006 Internet Systems Consortium, Inc. ("ISC") @@ -36,6 +37,7 @@ #include #include +#include /* * The functions are actually macros so that we can pick up the file and line @@ -79,17 +81,17 @@ BEGIN_DECLS * implementations that should not be called directly. */ void *x_calloc(size_t, size_t, const char *, int) - __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__)); + __attribute__((__alloc_size__(1, 2), __malloc__(free), __nonnull__)); void *x_malloc(size_t, const char *, int) - __attribute__((__alloc_size__(1), __malloc__, __nonnull__)); + __attribute__((__alloc_size__(1), __malloc__(free), __nonnull__)); void *x_realloc(void *, size_t, const char *, int) - __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3))); + __attribute__((__alloc_size__(2), __malloc__(free), __nonnull__(3))); void *x_reallocarray(void *, size_t, size_t, const char *, int) - __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4))); + __attribute__((__alloc_size__(2, 3), __malloc__(free), __nonnull__(4))); char *x_strdup(const char *, const char *, int) - __attribute__((__malloc__, __nonnull__)); + __attribute__((__malloc__(free), __nonnull__)); char *x_strndup(const char *, size_t, const char *, int) - __attribute__((__malloc__, __nonnull__)); + __attribute__((__malloc__(free), __nonnull__)); void x_vasprintf(char **, const char *, va_list, const char *, int) __attribute__((__nonnull__, __format__(printf, 2, 0))); -- 2.39.2