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>maint
parent
445f9f4f35
commit
6e3ea71639
|
@ -117,18 +117,46 @@ void reftable_free(void *p);
|
||||||
void *reftable_calloc(size_t nelem, size_t elsize);
|
void *reftable_calloc(size_t nelem, size_t elsize);
|
||||||
char *reftable_strdup(const char *str);
|
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_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,
|
static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,
|
||||||
size_t *allocp)
|
size_t *allocp)
|
||||||
{
|
{
|
||||||
void *new_p;
|
void *new_p;
|
||||||
size_t alloc = *allocp * 2 + 1;
|
size_t alloc = *allocp * 2 + 1, alloc_bytes;
|
||||||
if (alloc < nelem)
|
if (alloc < nelem)
|
||||||
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)
|
if (!new_p)
|
||||||
return p;
|
return p;
|
||||||
*allocp = alloc;
|
*allocp = alloc;
|
||||||
|
|
Loading…
Reference in New Issue