diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-08-13 22:50:51 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-08-13 22:53:38 -0700 |
commit | 34f25316966ae80059d8dcfe36103e4a986aeec5 (patch) | |
tree | 696851ac70e0692f95ba95fefb2346ceff022b11 /src | |
parent | 5785b374b554094d83ec84e838daf456cf0b9448 (diff) |
til_stream: always assign n_module_contexts in register
Leaving the larger n_module_contexts on reuse creates the
potential for a NULL ptr dereference in places like gc which
check the refcount of each countext in the set, without testing
for NULL.
Rather than making everything check for NULL, just shrink the
count when it gets reused in a smaller case. This whole reuse
thing is kind of a silly little optimization anyways, and will be
revisited when cloning either happens or the sets become
deprecated.
For now just prevent creating situations that can crash.
Diffstat (limited to 'src')
-rw-r--r-- | src/til_stream.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/til_stream.c b/src/til_stream.c index a5cc8e5..021e0d4 100644 --- a/src/til_stream.c +++ b/src/til_stream.c @@ -573,15 +573,17 @@ int til_stream_register_module_contexts(til_stream_t *stream, size_t n_contexts, } if (!c) { - c = calloc(1, sizeof(til_stream_module_context_t) + n_contexts * sizeof(contexts[0])); + c = calloc(1, sizeof(til_stream_module_context_t) + n_contexts * sizeof(c->module_contexts[0])); if (!c) return -ENOMEM; c->path_hash = path_hash; - c->n_module_contexts = n_contexts; } - /* XXX: note in the reused case c->n_contexts may exceed n_contexts, but they're NULL */ + /* Note in a reuse of a larger c than needed, its n_module_contexts shrinks.. otherwise we'd have to check + * for NULL slots in c->module_contexts[] everywhere they're iterated. + */ + c->n_module_contexts = n_contexts; for (size_t i = 0; i < n_contexts; i++) c->module_contexts[i] = til_module_context_ref(contexts[i]); |