diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-01-08 19:15:27 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-01-08 19:15:27 +0100 |
commit | 9dc05615d2d8fa220c7c8ebe54d16ecaad358a37 (patch) | |
tree | 3809be91681698f3ed41ac153425b3a85af5a4d2 | |
parent | 308f83f0f39886f39400fb79f42a22f853b03327 (diff) |
Check for overflow in array allocations
-rw-r--r-- | da.h | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -67,22 +67,29 @@ #ifndef MANGO_DA_H #define MANGO_DA_H -#define __da_s(a) (sizeof(*(a)->buf)) +#define DA_ALLOC(p, n) \ + do { \ + if ((n) && SIZE_MAX / (n) < sizeof(*(p))) { \ + errno = EOVERFLOW; \ + err(EXIT_FAILURE, "realloc"); \ + } \ + if (!((p) = realloc((p), (n) * sizeof(*(p))))) \ + err(EXIT_FAILURE, "realloc"); \ + } while (0) #define dainit(a, n) \ do { \ + (a)->buf = NULL; \ (a)->cap = n; \ (a)->len = 0; \ - if (!((a)->buf = malloc((a)->cap * __da_s(a)))) \ - err(EXIT_FAILURE, "malloc"); \ + DA_ALLOC((a)->buf, (a)->cap); \ } while (0) #define dapush(a, x) \ do { \ if ((a)->len >= (a)->cap) { \ (a)->cap = (a)->cap ? (a)->cap * 2 : 1; \ - if (!((a)->buf = realloc((a)->buf, (a)->cap * __da_s(a)))) \ - err(EXIT_FAILURE, "realloc"); \ + DA_ALLOC((a)->buf, (a)->cap); \ } \ (a)->buf[(a)->len++] = (x); \ } while (0) @@ -91,7 +98,8 @@ #define da_remove_range(a, i, j) \ do { \ - memmove((a)->buf + (i), (a)->buf + (j), ((a)->len - (j)) * __da_s(a)); \ + memmove((a)->buf + (i), (a)->buf + (j), \ + ((a)->len - (j)) * sizeof(*(a)->buf)); \ (a)->len -= j - i; \ } while (0) |