Commit e5ed410c authored by Simon McVittie's avatar Simon McVittie

Avoid calling Standard C string/array functions with NULL arguments

glibc string.h declares memcpy() with attribute(nonnull(1,2)), causing
calls with NULL arguments to be treated as undefined behaviour.
This is consistent with ISO C99 and C11, which state that passing 0
to string functions as an array length does not remove the requirement
that the pointer to the array is a valid pointer.
gcc -fsanitize=undefined catches this while running OSTree's test suite.

Similarly, running the GLib test suite reports similar issues for
qsort(), memmove(), memcmp().
Signed-off-by: Simon McVittie's avatarSimon McVittie <smcv@debian.org>
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=775510
Reviewed-by: Colin Walters
parent 5e7eaaaa
......@@ -262,7 +262,9 @@ buffer_read (Buffer *buffer,
char *dest,
gsize count)
{
memcpy (dest, buffer->data + buffer->start, count);
if (count != 0)
memcpy (dest, buffer->data + buffer->start, count);
buffer_consumed (buffer, count);
}
......@@ -293,9 +295,11 @@ grow_buffer (Buffer *buffer)
data = g_malloc (size);
in_buffer = buffer_data_size (buffer);
memcpy (data,
buffer->data + buffer->start,
in_buffer);
if (in_buffer != 0)
memcpy (data,
buffer->data + buffer->start,
in_buffer);
g_free (buffer->data);
buffer->data = data;
buffer->end -= buffer->start;
......
......@@ -300,9 +300,11 @@ grow_buffer (Buffer *buffer)
data = g_malloc (size);
in_buffer = buffer_data_size (buffer);
memcpy (data,
buffer->data + buffer->start,
in_buffer);
if (in_buffer != 0)
memcpy (data,
buffer->data + buffer->start,
in_buffer);
g_free (buffer->data);
buffer->data = data;
buffer->end -= buffer->start;
......
......@@ -506,7 +506,8 @@ add_token_result (const gchar *app_name,
static void
merge_token_results (gboolean first)
{
qsort (static_token_results, static_token_results_size, sizeof (struct search_result), compare_results);
if (static_token_results_size != 0)
qsort (static_token_results, static_token_results_size, sizeof (struct search_result), compare_results);
/* If this is the first token then we are basically merging a list with
* itself -- we only perform de-duplication.
......@@ -606,7 +607,8 @@ reset_total_search_results (void)
static void
sort_total_search_results (void)
{
qsort (static_total_results, static_total_results_size, sizeof (struct search_result), compare_categories);
if (static_total_results_size != 0)
qsort (static_total_results, static_total_results_size, sizeof (struct search_result), compare_categories);
}
static void
......@@ -620,9 +622,10 @@ merge_directory_results (void)
static_total_results = g_renew (struct search_result, static_total_results, static_total_results_allocated);
}
memcpy (static_total_results + static_total_results_size,
static_search_results,
static_search_results_size * sizeof (struct search_result));
if (static_total_results + static_total_results_size != 0)
memcpy (static_total_results + static_total_results_size,
static_search_results,
static_search_results_size * sizeof (struct search_result));
static_total_results_size += static_search_results_size;
......
......@@ -116,7 +116,9 @@ g_unix_socket_address_set_property (GObject *object,
/* Clip to fit in UNIX_PATH_MAX with zero termination or first byte */
len = MIN (array->len, UNIX_PATH_MAX-1);
memcpy (address->priv->path, array->data, len);
if (len != 0)
memcpy (address->priv->path, array->data, len);
address->priv->path[len] = 0; /* Ensure null-terminated */
address->priv->path_len = len;
}
......
......@@ -291,7 +291,8 @@ file_builder_add_string (FileBuilder *fb,
chunk->offset = fb->offset;
chunk->size = length;
chunk->data = g_malloc (length);
memcpy (chunk->data, string, length);
if (length != 0)
memcpy (chunk->data, string, length);
*start = guint32_to_le (fb->offset);
*size = guint16_to_le (length);
......
......@@ -415,6 +415,9 @@ g_array_append_vals (GArray *farray,
g_return_val_if_fail (array, NULL);
if (len == 0)
return farray;
g_array_maybe_expand (array, len);
memcpy (g_array_elt_pos (array, array->len), data,
......@@ -468,6 +471,9 @@ g_array_prepend_vals (GArray *farray,
g_return_val_if_fail (array, NULL);
if (len == 0)
return farray;
g_array_maybe_expand (array, len);
memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
......@@ -517,6 +523,9 @@ g_array_insert_vals (GArray *farray,
g_return_val_if_fail (array, NULL);
if (len == 0)
return farray;
g_array_maybe_expand (array, len);
memmove (g_array_elt_pos (array, len + index_),
......
......@@ -2361,7 +2361,10 @@ g_option_group_add_entries (GOptionGroup *group,
group->entries = g_renew (GOptionEntry, group->entries, group->n_entries + n_entries);
memcpy (group->entries + group->n_entries, entries, sizeof (GOptionEntry) * n_entries);
/* group->entries could be NULL in the trivial case where we add no
* entries to no entries */
if (n_entries != 0)
memcpy (group->entries + group->n_entries, entries, sizeof (GOptionEntry) * n_entries);
for (i = group->n_entries; i < group->n_entries + n_entries; i++)
{
......
......@@ -386,7 +386,7 @@ g_memdup (gconstpointer mem,
{
gpointer new_mem;
if (mem)
if (mem && byte_size != 0)
{
new_mem = g_malloc (byte_size);
memcpy (new_mem, mem, byte_size);
......
......@@ -74,7 +74,7 @@ typedef void (*GTestFixtureFunc) (gpointer fixture,
if (__l1 != __l2) \
g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
#l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", __l1, "==", __l2, 'i'); \
else if (memcmp (__m1, __m2, __l1) != 0) \
else if (__l1 != 0 && memcmp (__m1, __m2, __l1) != 0) \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
"assertion failed (" #m1 " == " #m2 ")"); \
} G_STMT_END
......
......@@ -3550,7 +3550,8 @@ g_type_children (GType type,
G_READ_LOCK (&type_rw_lock); /* ->children is relocatable */
children = g_new (GType, node->n_children + 1);
memcpy (children, node->children, sizeof (GType) * node->n_children);
if (node->n_children != 0)
memcpy (children, node->children, sizeof (GType) * node->n_children);
children[node->n_children] = 0;
if (n_children)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment