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 /server.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 'server.c')
| -rw-r--r-- | server.c | 24 |
1 files changed, 18 insertions, 6 deletions
@@ -58,12 +58,17 @@ int server_client_close(struct server *const s, struct server_client *const c) { memcpy(ref, ref + 1, s->n - i); - if (!(s->c = realloc(s->c, (s->n - 1) * sizeof *s->c))) + const size_t n = s->n - 1; + struct server_client *const c = realloc(s->c, n * sizeof *s->c); + + if (!c) { fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); return -1; } + + s->c = c; } else { @@ -127,19 +132,26 @@ static struct server_client *alloc_client(struct server *const s) __func__, strerror(errno)); return NULL; } - else if (!(s->c = realloc(s->c, (s->n + 1) * sizeof *s->c))) + + const size_t n = s->n + 1; + struct server_client *const clients = realloc(s->c, n * sizeof *s->c); + + if (!clients) { - fprintf(stderr, "%s: realloc(3): %s\n", - __func__, strerror(errno)); + fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno)); return NULL; } - s->c[s->n] = (const struct server_client) + struct server_client *const c = &clients[s->n]; + + *c = (const struct server_client) { .fd = fd }; - return &s->c[s->n++]; + s->c = clients; + s->n = n; + return c; } void server_client_write_pending(struct server_client *const c, |
