reftable/basics: stop using `st_mult()` in array allocators
We're using `st_mult()` as part of our macro helpers that allocate arrays. This is bad due two two reasons: - `st_mult()` causes us to die in case the multiplication overflows. - `st_mult()` ties us to the Git codebase. Refactor the code to instead detect overflows manually and return an error in such cases. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>main
parent
445f9f4f35
commit
6e3ea71639
|
@ -117,18 +117,46 @@ void reftable_free(void *p);
|
|||
void *reftable_calloc(size_t nelem, size_t elsize);
|
||||
char *reftable_strdup(const char *str);
|
||||
|
||||
#define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc)))
|
||||
static inline int reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)
|
||||
{
|
||||
if (nelem && elsize > SIZE_MAX / nelem)
|
||||
return -1;
|
||||
*out = nelem * elsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define REFTABLE_ALLOC_ARRAY(x, alloc) do { \
|
||||
size_t alloc_size; \
|
||||
if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
|
||||
errno = ENOMEM; \
|
||||
(x) = NULL; \
|
||||
} else { \
|
||||
(x) = reftable_malloc(alloc_size); \
|
||||
} \
|
||||
} while (0)
|
||||
#define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x)))
|
||||
#define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc)))
|
||||
#define REFTABLE_REALLOC_ARRAY(x, alloc) do { \
|
||||
size_t alloc_size; \
|
||||
if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
|
||||
errno = ENOMEM; \
|
||||
(x) = NULL; \
|
||||
} else { \
|
||||
(x) = reftable_realloc((x), alloc_size); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,
|
||||
size_t *allocp)
|
||||
{
|
||||
void *new_p;
|
||||
size_t alloc = *allocp * 2 + 1;
|
||||
size_t alloc = *allocp * 2 + 1, alloc_bytes;
|
||||
if (alloc < nelem)
|
||||
alloc = nelem;
|
||||
new_p = reftable_realloc(p, st_mult(elsize, alloc));
|
||||
if (reftable_alloc_size(elsize, alloc, &alloc_bytes) < 0) {
|
||||
errno = ENOMEM;
|
||||
return p;
|
||||
}
|
||||
new_p = reftable_realloc(p, alloc_bytes);
|
||||
if (!new_p)
|
||||
return p;
|
||||
*allocp = alloc;
|
||||
|
|
Loading…
Reference in New Issue