diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-03-04 02:06:19 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-20 23:52:51 +0200 |
| commit | 67ffb772b7488b84e37e6880290820fc54434b33 (patch) | |
| tree | 574f95ad5834282261846daede1f653b1d1d0666 /handler.c | |
| parent | 37fd5c92aebd87af14a1f73f8e567b8b74f6bd36 (diff) | |
Fix memory leak on failed realloc(3)
According to C99 ยง7.20.3.4:
If memory for the new object cannot be allocated, the old object is not
deallocated and its value is unchanged.
Therefore, a temporary pointer must be used to ensure the original
object can still be deallocated should realloc(3) return a null pointer.
Diffstat (limited to 'handler.c')
| -rw-r--r-- | handler.c | 26 |
1 files changed, 16 insertions, 10 deletions
@@ -310,27 +310,33 @@ struct handler *handler_alloc(const char *const tmpdir) int handler_add(struct handler *const h, const char *url, const enum http_op op, const handler_fn f, void *const user) { - if (!h || !(h->cfg = realloc(h->cfg, (h->n_cfg + 1) * sizeof *h->cfg))) + const size_t n = h->n_cfg + 1; + struct handler_cfg *const cfgs = realloc(h->cfg, n * sizeof *h->cfg), + *c = NULL; + + if (!cfgs) { fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); return -1; } - char *const new = strdup(url); - - if (!new) - { - fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno)); - return -1; - } + c = &cfgs[h->n_cfg]; - h->cfg[h->n_cfg++] = (const struct handler_cfg) + *c = (const struct handler_cfg) { - .url = new, + .url = strdup(url), .op = op, .f = f, .user = user }; + if (!c->url) + { + fprintf(stderr, "%s: strdup(3): %s\n", __func__, strerror(errno)); + return -1; + } + + h->cfg = cfgs; + h->n_cfg = n; return 0; } |
