summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-11 11:44:54 +0100
committerwm4 <wm4@nowhere>2014-11-11 19:47:08 +0100
commit12290a7e8666cafd501dc7a3a842a3b54c65e65b (patch)
treed021bf4a1ce893a0f89478f25835ce7ca5f58a27
parent11300cd37fc0038f3004b0da5748091f5f763738 (diff)
downloadlibass-12290a7e8666cafd501dc7a3a842a3b54c65e65b.tar.bz2
libass-12290a7e8666cafd501dc7a3a842a3b54c65e65b.tar.xz
Add ass_realloc_array()
Helps with overflow and allocation failure checking.
-rw-r--r--libass/ass_utils.c18
-rw-r--r--libass/ass_utils.h2
2 files changed, 20 insertions, 0 deletions
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 778da80..efb96a6 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -89,6 +89,24 @@ void ass_aligned_free(void *ptr)
free(*((void **)ptr - 1));
}
+/**
+ * This works similar to realloc(ptr, nmemb * size), but checks for overflow.
+ *
+ * Unlike some implementations of realloc, this never acts as a call to free().
+ * If the total size is 0, it is bumped up to 1. This means a NULL return always
+ * means allocation failure, and the unportable realloc(0, 0) case is avoided.
+ */
+void *ass_realloc_array(void *ptr, size_t nmemb, size_t size)
+{
+ if (nmemb > (SIZE_MAX / size))
+ return NULL;
+ size *= nmemb;
+ if (size < 1)
+ size = 1;
+
+ return realloc(ptr, size);
+}
+
void skip_spaces(char **str)
{
char *p = *str;
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index 6ae7328..5548a93 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -56,6 +56,8 @@ int has_avx2(void);
void *ass_aligned_alloc(size_t alignment, size_t size);
void ass_aligned_free(void *ptr);
+void *ass_realloc_array(void *ptr, size_t nmemb, size_t size);
+
void skip_spaces(char **str);
void rskip_spaces(char **str, char *limit);
int mystrtoi(char **p, int *res);