diff --git a/contrib/bc/NEWS.md b/contrib/bc/NEWS.md index 5d0126b821a8..9a354e537d9f 100644 --- a/contrib/bc/NEWS.md +++ b/contrib/bc/NEWS.md @@ -1,5 +1,13 @@ # News +## 5.2.2 + +This is a production release that fixes one bug, a segmentation fault if +`argv[0]` equals `NULL`. + +This is not a critical bug; there will be no vulnerability as far as I can tell. +There is no need to update if you do not wish to. + ## 5.2.1 This is a production release that fixes two parse bugs when in POSIX standard diff --git a/contrib/bc/configure.sh b/contrib/bc/configure.sh index 76ffb2b9a18e..fc66ffc51066 100755 --- a/contrib/bc/configure.sh +++ b/contrib/bc/configure.sh @@ -36,7 +36,7 @@ builddir=$(pwd) . "$scriptdir/scripts/functions.sh" # Simply prints the help message and quits based on the argument. -# @param val The value to pass to exit. Must be an integer. +# @param msg The help message to print. usage() { if [ $# -gt 0 ]; then @@ -95,7 +95,7 @@ usage() { printf ' -f, --force\n' printf ' Force use of all enabled options, even if they do not work. This\n' printf ' option is to allow the maintainer a way to test that certain options\n' - printf ' are not failing invisibly. (Development only.)' + printf ' are not failing invisibly. (Development only.)\n' printf ' -g, --debug\n' printf ' Build in debug mode. Adds the "-g" flag, and if there are no\n' printf ' other CFLAGS, and "-O" was not given, this also adds the "-O0"\n' @@ -535,7 +535,7 @@ gen_std_test_targets() { # This allows `make test_bc_errors` and `make test_dc_errors` to run in # parallel. # -# @param name Which calculator to generate tests for. +# @param name Which calculator to generate tests for. gen_err_tests() { _gen_err_tests_name="$1" diff --git a/contrib/bc/include/lang.h b/contrib/bc/include/lang.h index 705aca35df1c..09b0d6072806 100644 --- a/contrib/bc/include/lang.h +++ b/contrib/bc/include/lang.h @@ -37,6 +37,9 @@ #define BC_LANG_H #include +#if BC_C11 +#include +#endif // BC_C11 #include #include @@ -324,6 +327,11 @@ typedef enum BcInst { } BcInst; +#if BC_C11 +static_assert(BC_INST_INVALID <= UCHAR_MAX, + "Too many instructions to fit into an unsigned char"); +#endif // BC_C11 + /// Used by maps to identify where items are in the array. typedef struct BcId { diff --git a/contrib/bc/include/version.h b/contrib/bc/include/version.h index eca73baf508f..0c4122528e7d 100644 --- a/contrib/bc/include/version.h +++ b/contrib/bc/include/version.h @@ -37,6 +37,6 @@ #define BC_VERSION_H /// The current version. -#define VERSION 5.2.1 +#define VERSION 5.2.2 #endif // BC_VERSION_H diff --git a/contrib/bc/include/vm.h b/contrib/bc/include/vm.h index d6f698fb1e6d..6f69712a804b 100644 --- a/contrib/bc/include/vm.h +++ b/contrib/bc/include/vm.h @@ -545,8 +545,10 @@ typedef struct BcVm { /// The messages for each error. const char *err_msgs[BC_ERR_NELEMS]; +#if BC_ENABLE_NLS /// The locale. const char *locale; +#endif // BC_ENABLE_NLS #endif // !BC_ENABLE_LIBRARY diff --git a/contrib/bc/src/main.c b/contrib/bc/src/main.c index 38c87a415f2b..3146f983787e 100644 --- a/contrib/bc/src/main.c +++ b/contrib/bc/src/main.c @@ -37,7 +37,9 @@ #include #include +#if BC_ENABLE_NLS #include +#endif // BC_ENABLE_NLS #ifndef _WIN32 #include @@ -56,16 +58,34 @@ int main(int argc, char *argv[]) { char *name; size_t len = strlen(BC_EXECPREFIX); +#if BC_ENABLE_NLS // Must set the locale properly in order to have the right error messages. vm.locale = setlocale(LC_ALL, ""); +#endif // BC_ENABLE_NLS // Set the start pledge(). bc_pledge(bc_pledge_start, NULL); - // Figure out the name of the calculator we are using. We can't use basename - // because it's not portable, but yes, this is stripping off the directory. - name = strrchr(argv[0], BC_FILE_SEP); - vm.name = (name == NULL) ? argv[0] : name + 1; + // Sometimes, argv[0] can be NULL. Better make sure to be robust against it. + if (argv[0] != NULL) { + + // Figure out the name of the calculator we are using. We can't use + // basename because it's not portable, but yes, this is stripping off + // the directory. + name = strrchr(argv[0], BC_FILE_SEP); + vm.name = (name == NULL) ? argv[0] : name + 1; + } + else + { +#if !DC_ENABLED + vm.name = "bc"; +#elif !BC_ENABLED + vm.name = "dc"; +#else + // Just default to bc in that case. + vm.name = "bc"; +#endif + } // If the name is longer than the length of the prefix, skip the prefix. if (strlen(vm.name) > len) vm.name += len; diff --git a/contrib/bc/src/program.c b/contrib/bc/src/program.c index bc5b88011638..8ec1a011a26d 100644 --- a/contrib/bc/src/program.c +++ b/contrib/bc/src/program.c @@ -2718,7 +2718,6 @@ void bc_program_exec(BcProgram *p) { while (ip->idx < func->code.len) #endif // !BC_HAS_COMPUTED_GOTO { - BC_SIG_ASSERT_NOT_LOCKED; #if BC_HAS_COMPUTED_GOTO