This release assigns a default value to the internal program name
variable in case the program is invoked with argv[0] == NULL.
There was no security issue: the prevuous program version would have
been immediately terminated due to a NULL dereference.
(cherry picked from commit
00698711dee1d990d3db9c41bf58394e589eecfe)
# 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
. "$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
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'
# 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"
#define BC_LANG_H
#include <stdbool.h>
+#if BC_C11
+#include <assert.h>
+#endif // BC_C11
#include <status.h>
#include <vector.h>
} 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 {
#define BC_VERSION_H
/// The current version.
-#define VERSION 5.2.1
+#define VERSION 5.2.2
#endif // BC_VERSION_H
/// 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
#include <stdlib.h>
#include <string.h>
+#if BC_ENABLE_NLS
#include <locale.h>
+#endif // BC_ENABLE_NLS
#ifndef _WIN32
#include <libgen.h>
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;
while (ip->idx < func->code.len)
#endif // !BC_HAS_COMPUTED_GOTO
{
-
BC_SIG_ASSERT_NOT_LOCKED;
#if BC_HAS_COMPUTED_GOTO