diff options
author | wm4 <wm4@nowhere> | 2014-11-11 11:44:54 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-11 19:47:08 +0100 |
commit | 12290a7e8666cafd501dc7a3a842a3b54c65e65b (patch) | |
tree | d021bf4a1ce893a0f89478f25835ce7ca5f58a27 /libass | |
parent | 11300cd37fc0038f3004b0da5748091f5f763738 (diff) | |
download | libass-12290a7e8666cafd501dc7a3a842a3b54c65e65b.tar.bz2 libass-12290a7e8666cafd501dc7a3a842a3b54c65e65b.tar.xz |
Add ass_realloc_array()
Helps with overflow and allocation failure checking.
Diffstat (limited to 'libass')
-rw-r--r-- | libass/ass_utils.c | 18 | ||||
-rw-r--r-- | libass/ass_utils.h | 2 |
2 files changed, 20 insertions, 0 deletions
diff --git a/libass/ass_utils.c b/libass/ass_utils.c index 778da808..efb96a67 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 6ae73287..5548a931 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); |