mirror of https://github.com/mpv-player/mpv
ta: check overflow in array realloc macros
This commit is contained in:
parent
d4f37174a1
commit
2cad237f8b
1
ta/ta.h
1
ta/ta.h
|
@ -54,6 +54,7 @@ void *ta_find_parent(void *ptr);
|
|||
|
||||
// Utility functions
|
||||
size_t ta_calc_array_size(size_t element_size, size_t count);
|
||||
size_t ta_calc_prealloc_elems(size_t nextidx);
|
||||
void *ta_new_context(void *ta_parent);
|
||||
void *ta_steal_(void *ta_parent, void *ptr);
|
||||
void *ta_memdup(void *ta_parent, void *ptr, size_t size);
|
||||
|
|
|
@ -77,14 +77,17 @@ char *ta_talloc_asprintf_append_buffer(char *s, const char *fmt, ...) TA_PRF(2,
|
|||
|
||||
#define MP_TALLOC_ELEMS(p) (talloc_get_size(p) / sizeof((p)[0]))
|
||||
|
||||
#define MP_RESIZE_ARRAY(ctx, p, count) do { \
|
||||
(p) = talloc_realloc_size((ctx), p, (count) * sizeof((p)[0])); } while (0)
|
||||
#define MP_RESIZE_ARRAY(ctx, p, count) \
|
||||
do { \
|
||||
(p) = ta_xrealloc_size(ctx, p, \
|
||||
ta_calc_array_size(sizeof((p)[0]), count)); \
|
||||
} while (0)
|
||||
|
||||
#define MP_TARRAY_GROW(ctx, p, nextidx) \
|
||||
do { \
|
||||
size_t nextidx_ = (nextidx); \
|
||||
if (nextidx_ >= MP_TALLOC_ELEMS(p)) \
|
||||
MP_RESIZE_ARRAY(ctx, p, (nextidx_ + 1) * 2);\
|
||||
MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
|
||||
} while (0)
|
||||
|
||||
#define MP_GROW_ARRAY(p, nextidx) MP_TARRAY_GROW(NULL, p, nextidx)
|
||||
|
|
|
@ -30,6 +30,17 @@ size_t ta_calc_array_size(size_t element_size, size_t count)
|
|||
return element_size * count;
|
||||
}
|
||||
|
||||
// This is used when an array has to be enlarged for appending new elements.
|
||||
// Return a "good" size for the new array (in number of elements). This returns
|
||||
// a value >= nextidx, unless the calculation overflows, in which case SIZE_MAX
|
||||
// is returned.
|
||||
size_t ta_calc_prealloc_elems(size_t nextidx)
|
||||
{
|
||||
if (nextidx >= ((size_t)-1) / 2 - 1)
|
||||
return (size_t)-1;
|
||||
return (nextidx + 1) * 2;
|
||||
}
|
||||
|
||||
static void dummy_dtor(void *p){}
|
||||
|
||||
/* Create an empty (size 0) TA allocation, which is prepared in a way such that
|
||||
|
|
Loading…
Reference in New Issue