From 3614e5877818a3f3e187b43f8247cabaf842c39f Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sun, 19 Dec 2021 02:38:04 +0100 Subject: safer use of memcpy() and memchr(): we must not pass in NULL pointers * The C standard actually forbids this (undefined behaviour) even though it seems intuitive that something like `memcpy(foo, NULL, 0)` does no harm. * It turned out, there were actual real bugs related to this. If memchr() was called with a variable that can be NULL, the compiler could assume that the variable is actually always non-NULL (since glibc declares memchr() with nonnull), consequently eliminating checks for NULL afterwards. The same could theoretically happen with memcpy(). This manifested itself in the empty search crashing when building with -O3. Test case: sciteco -e '@S//' * Consequently, the nightly builds (at least for Ubuntu) also had this bug. * In some cases, the passed in pointers are passed down from the caller but should not be NULL, so I added runtime assertions to guard against it. --- src/goto-commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/goto-commands.c') diff --git a/src/goto-commands.c b/src/goto-commands.c index 792b4e3..eb4674b 100644 --- a/src/goto-commands.c +++ b/src/goto-commands.c @@ -109,7 +109,7 @@ teco_state_goto_done(teco_machine_main_t *ctx, const teco_string_t *str, GError teco_string_t label = {NULL, 0}; while (value > 0) { label.data = label.data ? label.data+label.len+1 : str->data; - const gchar *p = memchr(label.data, ',', str->len - (label.data - str->data)); + const gchar *p = label.data ? memchr(label.data, ',', str->len - (label.data - str->data)) : NULL; label.len = p ? p - label.data : str->len - (label.data - str->data); value--; -- cgit v1.2.3