summaryrefslogtreecommitdiffstats
path: root/ta
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-01-02 23:54:59 +0100
committerwm4 <wm4@nowhere>2014-01-02 23:54:59 +0100
commit2cad237f8bea862923bf9e7e2d7c55544f6248e0 (patch)
tree907febddd4fb439bfa8b1058140000a7516f8955 /ta
parentd4f37174a16afad6394e48e203abb41252e382d2 (diff)
downloadmpv-2cad237f8bea862923bf9e7e2d7c55544f6248e0.tar.bz2
mpv-2cad237f8bea862923bf9e7e2d7c55544f6248e0.tar.xz
ta: check overflow in array realloc macros
Diffstat (limited to 'ta')
-rw-r--r--ta/ta.h1
-rw-r--r--ta/ta_talloc.h9
-rw-r--r--ta/ta_utils.c11
3 files changed, 18 insertions, 3 deletions
diff --git a/ta/ta.h b/ta/ta.h
index c8a333f784..c21e0b0e39 100644
--- a/ta/ta.h
+++ b/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);
diff --git a/ta/ta_talloc.h b/ta/ta_talloc.h
index ff131a610e..409949495a 100644
--- a/ta/ta_talloc.h
+++ b/ta/ta_talloc.h
@@ -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)
diff --git a/ta/ta_utils.c b/ta/ta_utils.c
index 4d1e73fab6..a6b59f2e3d 100644
--- a/ta/ta_utils.c
+++ b/ta/ta_utils.c
@@ -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